Get GenericType-Name in good format using Reflection on C#
Using built-in functions and Linq this can be written
static string PrettyTypeName(Type t)
{
if (t.IsArray)
{
return PrettyTypeName(t.GetElementType()) + "[]";
}
if (t.IsGenericType)
{
return string.Format(
"{0}<{1}>",
t.Name.Substring(0, t.Name.LastIndexOf("`", StringComparison.InvariantCulture)),
string.Join(", ", t.GetGenericArguments().Select(PrettyTypeName)));
}
return t.Name;
}
NOTE: In pre-4.0 versions of C#, string.Join
requires explicit .ToArray()
:
string.Join(", ", t.GetGenericArguments().Select(PrettyTypeName).ToArray()));
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>