2009-10-07 7 views

Odpowiedz

11

Ok, zrobiłem grono badań i odkryłem, że typeof (List) ma "GetGenericArguments", który dostarczy ci podtypy. Zrobiłbym to w ten sposób (dla jednego rodzaju generycznego, jeśli jest to multi, zajmie to pętlę lub coś w tym stylu, na żądanie mogę opublikować funkcję.)

Oto funkcja do tego . wielokrotne generyczne argumenty „” zagnieżdżone typy generyczne Uchwyty redakcją ponownie, aby ta użyciu funkcji zbiorczej.

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

Należy nieco poprawić. Argument ogólny powinien być sformatowany w ten sam sposób, może to być typ ogólny. Oczywiście powinno to wspierać wiele ogólnych argumentów. –

+0

Byłem w trakcie pisania bardziej skomplikowanej wersji, która obsługiwała to i wielokrotności, które właśnie napisałem. – Erich

+0

Edytowany ponownie w celu użycia agregatów. Sprawdź historię edycji, jeśli chcesz "starą" wersję. Funkcjonalność jest identyczna, ale chciałem dowiedzieć się, jak działa agregacja, a to był dobry sposób na naukę :) – Erich

-1

Dobrze, że to dlatego, że nazwa typu w .NET faktycznie JEST List'1. "1" jest tak zwanym aritem generycznego i informuje o liczbie parametrów typu.

Jest to potrzebne, aby można było utworzyć więcej niż 1 ogólny typ o tej samej "nazwie", ale o innej liczbie ogólnych parametrów typu.

Na przykład istnieje więcej niż jeden typ "o nazwie" System.Action. Prawdziwe nazwy to System.Action'1, System.Action'2, System.Action'3 itd.

Jeśli więc wiesz, że Twój typ jest ogólny, możesz założyć, że jest to XX Koniec nazwy, więc możesz odciąć tę część, na przykład:

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

PS: Proszę zastąpić "z".

+0

Przepraszamy, w moim przykładzie wystąpił błąd.Potrzebuję argumentu typu generycznego (w moim przykładzie: Int32) – AndreyAkinshin

+0

Ta odpowiedź nie jest już istotna (po edycji pytania). – ToolmakerSteve

3

, który nie jest zbyt trudne ;-)

Ok, będę gryźć .. g Ten poniżej działa w trybie iniekcji i wyświetla prymitywne typy bez przestrzeni nazw (jak OP napisał):

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

Powstały cleanedName wygląda następująco: System.Collections.Generic.Dictionary<System.Collections.Generic.List<Int32>, ConsoleApplication2.Program+SomeType>

12

Używanie wbudowanych funkcji i LINQ to można zapisać

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

UWAGA: w starszej wersji C# kompilator wymaga wyraźnej .ToArray():

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

To powinna być zaakceptowana odpowiedź: –

+0

W VS 2010 z .NET 3.5 (nie wiem która wersja C#), 't.GetGenericArguments(). (PrettyTypeName) 'daje błąd kompilatora" * nie można przekonwertować z "System.Collections.Generic.IEnumerable " na 'string []' * "Napraw: dodaj' .ToArray() '. Dodawanie do odpowiedzi jako alternatywa. – ToolmakerSteve

0

Kolejny przykład, który napisałem sam przed potknięciem się tutaj.

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

Stare pytanie, ale dziś tego potrzebuję. Napisałem więc metodę rozszerzenia, która może wyświetlać ładnie wyglądającą ogólną nazwę w języku C#, która może obsługiwać wielopoziomowe typy generyczne zagnieżdżone.

Powiązane problemy