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>>

Tags:

C#

Generics