public static void Main()
Console.WriteLine(typeof(outer.Test<>).GetTypeName());
Console.WriteLine(typeof(outer.Test<other.inner>).GetTypeName());
Console.WriteLine(typeof(outer.Test<>).GetTypeName());
public static class TypeEx
public static string GetTypeName(this Type type)
throw new ArgumentNullException(nameof(type));
return type.GetNestedTypeName();
StringBuilder stringBuilder = new StringBuilder();
_buildClassNameRecursiv(type, stringBuilder);
return stringBuilder.ToString();
private static void _buildClassNameRecursiv(Type type, StringBuilder classNameBuilder, int genericParameterIndex = 0)
if (type.IsGenericParameter)
classNameBuilder.AppendFormat("T{0}", genericParameterIndex + 1);
else if (type.IsGenericType)
classNameBuilder.Append(GetNestedTypeName(type) + "[");
foreach (Type genericTypeArgument in type.GetGenericArguments())
classNameBuilder.Append(":");
_buildClassNameRecursiv(genericTypeArgument, classNameBuilder, subIndex++);
classNameBuilder.Append("]");
classNameBuilder.Append(type.GetNestedTypeName());
public static string GetNestedTypeName(this Type type)
throw new ArgumentNullException(nameof(type));
StringBuilder nestedName = new StringBuilder();
nestedName.Insert(0,'.');
nestedName.Insert(0, _getTypeName(type));
type = type.DeclaringType;
return nestedName.ToString();
private static string _getTypeName(Type type)
return type.IsGenericType ? type.Name.Split('`')[0]: type.Name;