Get the type name
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.
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.
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>>