C#:"漂亮"的类型名称功能?

Har*_*yer 19 c# generics types pretty-print

在泛型类型的情况下,System.Type类的名称属性返回奇怪的结果.有没有办法以更接近我指定方式的格式获取类型名称?例:typeof(List<string>).OriginalName == "List<string>"

vcs*_*nes 30

"漂亮"名称的问题是它们根据您使用的语言而有所不同.想象一下,如果OriginalName返回C#语法,VB.NET开发人员会感到惊讶.

但是,自己做这件事非常容易:

private static string PrettyName(Type type)
{
    if (type.GetGenericArguments().Length == 0)
    {
        return type.Name;
    }
    var genericArguments = type.GetGenericArguments();
    var typeDefeninition = type.Name;
    var unmangledName = typeDefeninition.Substring(0, typeDefeninition.IndexOf("`"));
    return unmangledName + "<" + String.Join(",", genericArguments.Select(PrettyName)) + ">";
}
Run Code Online (Sandbox Code Playgroud)

这将递归地解析非托管名称,这样如果你有类似的东西Dictionary<string, IList<string>>应该仍然有用.

  • 理想情况下,这需要进一步开发来处理类型,如`Dictionary <string,IList <string >> .KeyCollection`.它的CLR类型名称是`Dictionary \`2 + KeyCollection [System.String,IList \`1 [System.String]]`(给予或获取命名空间限定符).此外,你可以拥有像`Outer \`1 + Inner \`1 [OuterArg,InnerArg]`这样的东西.当然,您可以拥有数组(1D 2D等)和指向通用类型的指针,这些指针需要处理.:) (6认同)

Nav*_*ani 16

CodeDomProvider以前转换为c#:

    public static string GetOriginalName(this Type type)
    {
        string TypeName = type.FullName.Replace(type.Namespace + ".", "");//Removing the namespace

        var provider = System.CodeDom.Compiler.CodeDomProvider.CreateProvider("CSharp"); //You can also use "VisualBasic"
        var reference = new System.CodeDom.CodeTypeReference(TypeName);

        return provider.GetTypeOutput(reference);
    }
Run Code Online (Sandbox Code Playgroud)


Har*_*yer 0

我明白了,我必须自己写这个。这是我的解决方案(实际上比要求的要多一些)。这可能是有帮助的。

using System.Reflection;
using HWClassLibrary.Debug;
using System.Collections.Generic;
using System.Linq;
using System;

namespace HWClassLibrary.Helper
{
    public static class TypeNameExtender
    {
        private static IEnumerable<Type> _referencedTypesCache;

        public static void OnModuleLoaded() { _referencedTypesCache = null; }

        public static string PrettyName(this Type type)
        {
            if(type == typeof(int))
                return "int";
            if(type == typeof(string))
                return "string";

            var result = PrettyTypeName(type);
            if(type.IsGenericType)
                result = result + PrettyNameForGeneric(type.GetGenericArguments());
            return result;
        }

        private static string PrettyTypeName(Type type)
        {
            var result = type.Name;
            if(type.IsGenericType)
                result = result.Remove(result.IndexOf('`'));

            if (type.IsNested && !type.IsGenericParameter)
                return type.DeclaringType.PrettyName() + "." + result;

            if(type.Namespace == null)
                return result;

            var conflictingTypes = ReferencedTypes
                .Where(definedType => definedType.Name == type.Name && definedType.Namespace != type.Namespace)
                .ToArray();

            var namespaceParts = type.Namespace.Split('.').Reverse().ToArray();
            var namespacePart = "";
            for(var i = 0; i < namespaceParts.Length && conflictingTypes.Length > 0; i++)
            {
                namespacePart = namespaceParts[i] + "." + namespacePart;
                conflictingTypes = conflictingTypes
                    .Where(conflictingType => (conflictingType.Namespace + ".").EndsWith(namespacePart))
                    .ToArray();
            }

            return namespacePart + result;
        }

        private static IEnumerable<Type> ReferencedTypes
        {
            get
            {
                if(_referencedTypesCache == null)
                    _referencedTypesCache = Assembly.GetEntryAssembly().GetReferencedTypes();
                return _referencedTypesCache;
            }
        }

        private static string PrettyNameForGeneric(Type[] types)
        {
            var result = "";
            var delim = "<";
            foreach(var t in types)
            {
                result += delim;
                delim = ",";
                result += t.PrettyName();
            }
            return result + ">";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)