2009-10-07 26 views

回答

11

好吧,我已經做了一大堆的研究,發現的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(); 
} 
+0

應該加強一點。泛型參數的格式應該是相同的,它可能是一個泛型類型。當然,它應該支持許多通用的論點。 – 2009-10-07 18:31:44

+0

我正在輸入一個更復雜的版本來處理這個和多個,我剛剛發佈。 – Erich 2009-10-07 18:34:34

+0

再次編輯以使用聚合。如果你想要'舊'版本,請檢查編輯歷史記錄。功能是相同的,但我想弄清楚如何彙總工作,這是一個很好的方式來學習:) – Erich 2009-10-07 18:51:52

-1

嗯,這是因爲在.NET類型的名稱實際上是List'1。 「1」是泛型的所謂arity,它告訴你有多少個類型參數。

它的需要,這樣就可以創造更多的則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:請用'替換'。

+0

對不起,在我的例子是錯誤的。我需要獲得泛型類型的參數(在我的示例中:Int32) – AndreyAkinshin 2009-10-07 18:06:40

+0

此答案不再相關(在編輯問題之後)。 – ToolmakerSteve 2017-08-07 05:51:47

3

,是不是太硬;-)

好吧,我會咬.. 。下一個工作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>

12

使用內置的功能和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())); 
+1

這應該是被接受的答案 – 2016-09-30 07:49:21

+0

在VS 2010與.NET 3.5(不知道哪個C#版本),t.GetGenericArguments()。Select (PrettyTypeName)'給編譯器錯誤「*不能從'System.Collections.Generic.IEnumerable '轉換爲'string []'*「修正:追加'.ToArray()'。作爲替代方案添加答案。 – ToolmakerSteve 2017-08-07 05:41:54

0

另一個例子,我在這裏磕磕絆絆地寫了自己。

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; 
     } 
    } 
0

老問題,但我今天只需要這個。所以我寫了一個擴展方法,可以輸出漂亮的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('>'); 
    } 
}