How i can get full right name of generic type?
For example: This code
typeof(List).Name
return
If you have an instance of the list, you can call .ToString() and get the following
System.Collections.Generic.List`1[System.String]
This is in addition to the methods provided by the other answers directly against the type rather than the instance.
Edit: On your edit, I do not believe it is possible without providing your own parsing method, as List<string>
is C# shorthand for how the type is implemented, sort of like if you wrote typeof(int).ToString()
, what is captured is not "int" but the CTS name, System.Int32.
If you want the base generic type used:
List<string> lstString = new List<string>();
Type type = lstString.GetType().GetGenericTypeDefinition();
Assuming that you want to use the type do do something and that you don't really need the actual string definition which isn't all that useful.
Use the FullName property.
typeof(List<string>).FullName
That will give you the namespace + class + type parameters.
What you are asking for is a C# specific syntax. As far as .NET is concerned, this is proper:
System.Collections.Generic.List`1[System.String]
So to get what you want, you'd have to write a function to build it the way you want it. Perhaps like so:
static string GetCSharpRepresentation( Type t, bool trimArgCount ) {
if( t.IsGenericType ) {
var genericArgs = t.GetGenericArguments().ToList();
return GetCSharpRepresentation( t, trimArgCount, genericArgs );
}
return t.Name;
}
static string GetCSharpRepresentation( Type t, bool trimArgCount, List<Type> availableArguments ) {
if( t.IsGenericType ) {
string value = t.Name;
if( trimArgCount && value.IndexOf("`") > -1 ) {
value = value.Substring( 0, value.IndexOf( "`" ) );
}
if( t.DeclaringType != null ) {
// This is a nested type, build the nesting type first
value = GetCSharpRepresentation( t.DeclaringType, trimArgCount, availableArguments ) + "+" + value;
}
// Build the type arguments (if any)
string argString = "";
var thisTypeArgs = t.GetGenericArguments();
for( int i = 0; i < thisTypeArgs.Length && availableArguments.Count > 0; i++ ) {
if( i != 0 ) argString += ", ";
argString += GetCSharpRepresentation( availableArguments[0], trimArgCount );
availableArguments.RemoveAt( 0 );
}
// If there are type arguments, add them with < >
if( argString.Length > 0 ) {
value += "<" + argString + ">";
}
return value;
}
return t.Name;
}
For these types (with true as 2nd param):
typeof( List<string> ) )
typeof( List<Dictionary<int, string>> )
It returns:
List<String>
List<Dictionary<Int32, String>>
In general though, I'd bet you probably don't need to have the C# representation of your code and perhaps if you do, some format better than the C# syntax would be more appropriate.
You could use this:
public static string GetTypeName(Type t) {
if (!t.IsGenericType) return t.Name;
if (t.IsNested && t.DeclaringType.IsGenericType) throw new NotImplementedException();
string txt = t.Name.Substring(0, t.Name.IndexOf('`')) + "<";
int cnt = 0;
foreach (Type arg in t.GetGenericArguments()) {
if (cnt > 0) txt += ", ";
txt += GetTypeName(arg);
cnt++;
}
return txt + ">";
}
For example:
static void Main(string[] args) {
var obj = new Dictionary<string, Dictionary<HashSet<int>, int>>();
string s = GetTypeName(obj.GetType());
Console.WriteLine(s);
Console.ReadLine();
}
Output:
Dictionary<String, Dictionary<HashSet<Int32>, Int32>>