在C#中获取泛型类型的用户友好名称

Awk*_*der 17 .net c# reflection

有没有编写递归方法的简单方法,它会为类中的泛型类型提供"用户友好"的名称Type

例如,对于以下代码,我想要"List <Dictionary <Int >>",而不是以下代码给出的简写或全名:

var list = new List<Dictionary<int, string>>();
var type = list.GetType();

Console.WriteLine(type.Name);
Console.WriteLine(type.FullName);
Run Code Online (Sandbox Code Playgroud)

Kir*_*oll 31

根据您编辑的问题,您需要以下内容:

public static string GetFriendlyName(this Type type)
{
    if (type == typeof(int))
        return "int";
    else if (type == typeof(short))
        return "short";
    else if (type == typeof(byte))
        return "byte";
    else if (type == typeof(bool)) 
        return "bool";
    else if (type == typeof(long))
        return "long";
    else if (type == typeof(float))
        return "float";
    else if (type == typeof(double))
        return "double";
    else if (type == typeof(decimal))
        return "decimal";
    else if (type == typeof(string))
        return "string";
    else if (type.IsGenericType)
        return type.Name.Split('`')[0] + "<" + string.Join(", ", type.GetGenericArguments().Select(x => GetFriendlyName(x)).ToArray()) + ">";
    else
        return type.Name;
}
Run Code Online (Sandbox Code Playgroud)

  • @hvd,是的,我并不真正关心OP的任意和虚假要求. (5认同)
  • 我建议使用`FullName`和Substring ...你也可以在`.`上使用split,只需要在最后一个`之后留下任何东西. (2认同)

小智 14

您可以通过调用已经为您提供的递归方法来避免编写递归方法:

static string GetTypeName(Type type)
{
    var codeDomProvider = CodeDomProvider.CreateProvider("C#");
    var typeReferenceExpression = new CodeTypeReferenceExpression(new CodeTypeReference(type));
    using (var writer = new StringWriter())
    {
        codeDomProvider.GenerateCodeFromExpression(typeReferenceExpression, writer, new CodeGeneratorOptions());
        return writer.GetStringBuilder().ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这包括类型命名空间,但不包括程序集引用.对于您问题中的类型,结果如下所示:

System.Collections.Generic.List<System.Collections.Generic.Dictionary<int, string>>
Run Code Online (Sandbox Code Playgroud)

我不清楚这是否符合"类似的东西" List<Dictionary<int, string>>.


Phi*_*hil 6

当我需要解决方案时,我使用了此代码:

    public static string FriendlyName(this Type type)
    {
        if (type.IsGenericType)
        {
            var namePrefix = type.Name.Split(new [] {'`'}, StringSplitOptions.RemoveEmptyEntries)[0];
            var genericParameters = type.GetGenericArguments().Select(FriendlyName).ToCsv();
            return namePrefix + "<" + genericParameters + ">";
        }

        return type.Name;
    }
Run Code Online (Sandbox Code Playgroud)

    public static string ToCsv(this IEnumerable<object> collectionToConvert, string separator = ", ")
    {
        return String.Join(separator, collectionToConvert.Select(o => o.ToString()));
    }
Run Code Online (Sandbox Code Playgroud)

用法示例:

    var typeDisplayText = MyDataModel.GetType().FriendlyName();
Run Code Online (Sandbox Code Playgroud)

...如果您正在创建自动生成的开发人员帮助页面,这也很有用,因为它包含通用参数名称:

public static string DefinitionTitle(this Type type)
    {
        if (type.IsGenericType)
        {
            var namePrefix = type.Name.Split(new[] { '`' }, StringSplitOptions.RemoveEmptyEntries)[0];
            var genericParameters = type.GetGenericArguments().Select(a => a.Name).ToCsv();
            return namePrefix + "<" + genericParameters + ">";
        }

        return type.Name;
    }
Run Code Online (Sandbox Code Playgroud)

用法示例:

    var typeDefinitionText = typeof(Dictionary<,>).DefinitionTitle());
Run Code Online (Sandbox Code Playgroud)