使用C#的反射获取GenericType名在良好的格式(Get GenericType-Name i

2019-07-21 07:34发布

我需要在其代码申报的形式获得通用型的名称。

例如:对于名单<的Int32>我想获得字符串“名单<的Int32>”。 非标准属性Type.Name在这种情况下返回“List`1”。

编辑:例如固定

Answer 1:

好吧,我已经做了一大堆的研究,发现的typeof(名单)具有“GetGenericArguments”,这将让你的子名。 所以,我会做这种方式(1种泛型类型,如果它是一个多它会采取一个循环类的东西。如果要求我可以发布一个函数,该函数。

这里是一个函数有多个通用参数,手柄“嵌套”泛型类型做。 再次编辑,使这个使用聚合函数:

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();
}


Answer 2:

使用内置的功能和LINQ这可以写成

static string PrettyTypeName(Type t)
{
    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;
}

注:在旧版本的C#,编译器需要明确的.ToArray()

            string.Join(", ", t.GetGenericArguments().Select(PrettyTypeName).ToArray()));


Answer 3:

这是不是太硬。 ;-)

好吧,我会咬...下文G的作品之一recusively并显示原始类型W / O命名空间(如OP写道):

  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))
            + ">";
  }

将所得cleanedName看起来像这样: System.Collections.Generic.Dictionary<System.Collections.Generic.List<Int32>, ConsoleApplication2.Program+SomeType>



Answer 4:

又如我在这里跌倒之前写我自己。

    private string PrettyPrintGenericTypeName(Type p)
    {
        if (p.IsGenericType) {
            var simpleName = p.Name.Substring(0, p.Name.IndexOf('`'));
            var genericTypeParams = p.GenericTypeArguments.Select(PrettyPrintGenericTypeName).ToList();
            return string.Format("{0}<{1}>", simpleName, string.Join(", ", genericTypeParams));
        } else {
            return p.Name;
        }
    }


Answer 5:

老问题,但我只有这个今天的需要。 所以我写了,可以输出漂亮的C# - 格式化,可以处理多层嵌套泛型类型的通用名称的扩展方法。

using System;
using System.Text;

public static class TypeExtensions
{
    public static string GetNiceName(this Type type, bool useFullName = false)
    {
        if (!type.IsGenericType) {
            return type.Name;
        }

        var typeNameBuilder = new StringBuilder();
        GetNiceGenericName(typeNameBuilder, type, useFullName);
        return typeNameBuilder.ToString();
    }

    static void GetNiceGenericName(StringBuilder sb, Type type, bool useFullName)
    {
        if (!type.IsGenericType) {
            sb.Append(useFullName ? type.FullName : type.Name);
            return;
        }

        var typeDef = type.GetGenericTypeDefinition();
        var typeName = useFullName ? typeDef.FullName : typeDef.Name;
        sb.Append(typeName);
        sb.Length -= typeName.Length - typeName.LastIndexOf('`');
        sb.Append('<');
        foreach (var typeArgument in type.GenericTypeArguments) {
            GetNiceGenericName(sb, typeArgument, useFullName);
            sb.Append(", ");
        }
        sb.Length -= 2;
        sb.Append('>');
    }
}


Answer 6:

如果不删除的命名空间的名称,只是说:

Regex.Replace(""+@type, @"`\d+\[", "<").Replace("]", ">");

如果你这样做,说:

Regex.Replace(Regex.Replace(""+@type, @"`\d+\[", "<").Replace("]", ">"), @"\w+\.", "")


Answer 7:

嗯,这是因为在.NET类型的名称实际上是List'1。 在““1" 是通用的所谓的元数,它会告诉你有多少类型的参数也有。

它的需要,这样就可以创造更多的则1种泛型类型相同的“名字”,但不同数量的泛型类型参数。

例如,有超过1型“称为” System.Action。 这些真正的名字是System.Action'1,System.Action'2,System.Action'3等。

所以,如果你知道你的类型是通用的,你可以假设有在名称末尾这个“XX,所以你可以只削减这部分了,例如像这样:

string strTypeName = typeof(List<>).Name.Substring(0, typeof(List<>).Name.LastIndexOf("`"));

PS:请以'替换'。



文章来源: Get GenericType-Name in good format using Reflection on C#