Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the type name

Tags:

c#

generics

How i can get full right name of generic type?

For example: This code

typeof(List<string>).Name

return

List`1

instead of

List<string>

How to get a right name?

typeof(List<string>).ToString()

returns System.Collections.Generic.List`1[System.String] but i want to get initial name:

List<string>

Is it real?

like image 800
Neir0 Avatar asked Apr 05 '10 17:04

Neir0


People also ask

How to Get a type by its name C#?

To load a type by name, you either need it's full name (if the assembly has already been loaded into the appdomain) or its Assembly Qualified name. The full name is the type's name, including the namespace. You can get that by calling Type. GetType(typeof(System.

How to Get type of assembly in C#?

GetType(String, Boolean, Boolean) Gets the Type object with the specified name in the assembly instance, with the options of ignoring the case, and of throwing an exception if the type is not found.

What is typeof in C#?

The C# typeof operator ( GetType operator in Visual Basic) is used to get a Type object representing String. From this Type object, the GetMethod method is used to get a MethodInfo representing the String. Substring overload that takes a starting location and a length.


3 Answers

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.

like image 94
Adam Sills Avatar answered Oct 20 '22 21:10

Adam Sills


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>>
like image 29
Hans Passant Avatar answered Oct 20 '22 22:10

Hans Passant


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.

like image 2
Anthony Pegram Avatar answered Oct 20 '22 21:10

Anthony Pegram