Hello everybody. I need to get the name of generic-type in form of its declaration in code.
For example: For List<Int32> I want to get string "List<Int32>". Standart property Type.Name returns "List`1" in this situation.
EDIT: example was fixed
Hello everybody. I need to get the name of generic-type in form of its declaration in code.
For example: For List<Int32> I want to get string "List<Int32>". Standart property Type.Name returns "List`1" in this situation.
EDIT: example was fixed
Well, that's because the name of the type in .NET actually IS List'1. The "'1" is the so called arity of the generic, and it tells you how many type parameters there are.
It's needed so that you can create more then 1 generic type with the same "name" but a different number of generic type parameters.
For example, there are more than 1 type "called" System.Action. The real names of these are System.Action'1, System.Action'2, System.Action'3 etc.
So, if you know that your type is generic, you can assume that there is this 'XX at the end of the name, so you could just cut this part away, for example like this:
string strTypeName = typeof(List<>).Name.Substring(0, typeof(List<>).Name.LastIndexOf("`"));
PS: Please replace ' with `.
Ok, I've done a bunch of research, and discovered that typeof(List) has "GetGenericArguments" which will get you the sub names. So I'd do it this way (for 1 generic type, if it is a multi it'll take a loop or something. I can post a function for that if requested.
Here is a function to do it with multiple generic arguments, handles 'nested' generic types. Edited again to make this use the Aggregate function:
static string GetFullName(Type t)
{
if (!t.IsGenericType)
return t.Name;
StringBuilder sb=new StringBuilder();
sb.Append(t.Name.Substring(0, t.Name.LastIndexOf("`")));
sb.Append(t.GetGenericArguments().Aggregate("<",
delegate(string aggregate,Type type)
{
return aggregate + (aggregate == "<" ? "" : ",") + GetFullName(type);
}
));
sb.Append(">");
return sb.ToString();
}
That isn't too hard. ;-)
Okay, I'll bite... g The one below works recusively and displays primitive types w/o namespace (like the OP wrote):
static string PrettyPrintGenericTypeName(Type typeRef)
{
var rootType = typeRef.IsGenericType
? typeRef.GetGenericTypeDefinition()
: typeRef;
var cleanedName = rootType.IsPrimitive
? rootType.Name
: rootType.ToString();
if (!typeRef.IsGenericType)
return cleanedName;
else
return cleanedName.Substring(0,
cleanedName.LastIndexOf('`'))
+ typeRef.GetGenericArguments()
.Aggregate("<",
(r, i) =>
r
+ (r != "<" ? ", " : null)
+ PrettyPrintGenericTypeName(i))
+ ">";
}
The resulting cleanedName looks like this: System.Collections.Generic.Dictionary<System.Collections.Generic.List<Int32>, ConsoleApplication2.Program+SomeType>