Get type name without any generics info

后端 未结 3 2024
清酒与你
清酒与你 2021-01-07 17:25

If I write:

var type = typeof(List);
Console.WriteLine(type.Name);

It will write:

List`1

相关标签:
3条回答
  • 2021-01-07 18:06

    No, it doesn't, because the "generic-type-string" is part of the name of type.

    0 讨论(0)
  • 2021-01-07 18:15

    If someone is interested, I created some extensionmethods for this problem that create a more "readable" string

    it produces something like

    List[string]
    outer.inner[other.whatever]
    IEnumerable[T0]
    Dictionary[string:int]
    

    Test here

    public static class TypeEx
    {
        public static string GetTypeName(this Type type)
        {
            if (type == null)
                throw new ArgumentNullException(nameof(type));
    
            if (!type.IsGenericType)
                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) + "[");
                int subIndex = 0;
                foreach (Type genericTypeArgument in type.GetGenericArguments())
                {
                    if (subIndex > 0)
                        classNameBuilder.Append(":");
    
                    _buildClassNameRecursiv(genericTypeArgument, classNameBuilder, subIndex++);
                }
                classNameBuilder.Append("]");
            }
            else
                classNameBuilder.Append(type.GetNestedTypeName());
        }
    
        public static string GetNestedTypeName(this Type type)
        {
            if (type == null)
                throw new ArgumentNullException(nameof(type));
            if (!type.IsNested)
                return type.Name;
    
            StringBuilder nestedName = new StringBuilder();
            while(type != null)
            {
                if(nestedName.Length>0)
                    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;
        }
    }
    
    0 讨论(0)
  • 2021-01-07 18:18

    No, it makes perfect sense for it to include the generic arity in the name - because it's part of what makes the name unique (along with assembly and namespace, of course).

    Put it this way: System.Nullable and System.Nullable<T> are very different types. It's not expected that you'd want to confuse the two... so if you want to lose information, you're going to have to work to do it. It's not very hard, of course, and can be put in a helper method:

    public static string GetNameWithoutGenericArity(this Type t)
    {
        string name = t.Name;
        int index = name.IndexOf('`');
        return index == -1 ? name : name.Substring(0, index);
    }
    

    Then:

    var type = typeof(List<string>);
    Console.WriteLine(type.GetNameWithoutGenericArity());
    
    0 讨论(0)
提交回复
热议问题