Uzyskaj nazwę typu bez pełnej przestrzeni nazw


293

Mam następujący kod:

return "[Inserted new " + typeof(T).ToString() + "]";

Ale

 typeof(T).ToString()

zwraca pełną nazwę wraz z przestrzenią nazw

Czy w ogóle istnieje możliwość uzyskania nazwy klasy (bez żadnych kwalifikatorów przestrzeni nazw?)


7
Nawiasem mówiąc, pisanie string1 + anything.ToString() + string2jest zbędne. ToStringJeśli to zrobisz, kompilator wstawi wywołanie automatycznie string1 + anything + string2.
— Tim Robinson,

13
nie brzmi to surowo, ale gdybyś sprawdził, jakie właściwości są dostępne w Typeinstancji (w odpowiedzi typeof(..)), jestem pewien, że sam to
— odkryjesz

Odpowiedzi:


530
typeof(T).Name // class name, no namespace
typeof(T).FullName // namespace and class name
typeof(T).Namespace // namespace, no class name

5
Namenie uwzględnia parametrów typu.
— gregsdennis

73
Albo this.GetType().Name, this.GetType().FullNameitp jeśli do czynienia z przypadkami.
— avenmore

1
Namerównież nie uwzględnia typów zagnieżdżonych!
— Warlike Chimpanzee,

33

Wypróbuj to, aby uzyskać parametry typu dla typów ogólnych:

public static string CSharpName(this Type type)
{
    var sb = new StringBuilder();
    var name = type.Name;
    if (!type.IsGenericType) return name;
    sb.Append(name.Substring(0, name.IndexOf('`')));
    sb.Append("<");
    sb.Append(string.Join(", ", type.GetGenericArguments()
                                    .Select(t => t.CSharpName())));
    sb.Append(">");
    return sb.ToString();
}

Może nie najlepsze rozwiązanie (z powodu rekurencji), ale działa. Wyjścia wyglądają następująco:

Dictionary<String, Object>

3
To powinna być zaakceptowana odpowiedź, ponieważ odpowiednio uwzględnia ogólne typy, które mogą się powtarzać (na przykład Słownik <int ?, int?>).
— Otis,

+1 za koncept. Ale nie lubię nieudanej przedwczesnej optymalizacji. Tworzy nowe StringBuilder w każdym wywołaniu rekurencyjnym (nawet podstawowym, gdy nie jest używane), ale ignoruje string.Jointymczasową i LINQ lambda. Po prostu używaj, Stringdopóki nie zorientujesz się, że to wąskie gardło. / rant
— Nigel Touch

1
Nigel, jest tam napisane, że prawdopodobnie nie jest to najlepsze rozwiązanie :)
— gregsdennis

ShortName to krótsza nazwa :)
— Valera



5

Po C # 6.0 (włącznie) możesz użyć nameof expression:

using Stuff = Some.Cool.Functionality  
class C {  
    static int Method1 (string x, int y) {}  
    static int Method1 (string x, string y) {}  
    int Method2 (int z) {}  
    string f<T>() => nameof(T);  
}  

var c = new C()  

nameof(C) -> "C"  
nameof(C.Method1) -> "Method1"   
nameof(C.Method2) -> "Method2"  
nameof(c.Method1) -> "Method1"   
nameof(c.Method2) -> "Method2"  
nameof(z) -> "z" // inside of Method2 ok, inside Method1 is a compiler error  
nameof(Stuff) = "Stuff"  
nameof(T) -> "T" // works inside of method but not in attributes on the method  
nameof(f) -> “f”  
nameof(f<T>) -> syntax error  
nameof(f<>) -> syntax error  
nameof(Method2()) -> error “This expression does not have a name”  

Uwaga! nameofnie pobiera typu środowiska wykonawczego obiektu bazowego, jest to tylko argument czasu kompilacji. Jeśli metoda akceptuje IEnumerable, nameof po prostu zwraca „IEnumerable”, podczas gdy rzeczywistym obiektem może być „List”.


3
nameofnie zwraca nazwyType
— Nigel Touch

@NigelTouch Sprawdziłem i zwróciłem nameofnazwę Typezrzutu ekranu z dowodem: prntscr.com/irfk2c
— Stas Boyarincev

1
Przepraszam, nie wyjaśniłem dobrze. Chodzi mi o to, że nie pobiera środowiska wykonawczego obiektu bazowego Type, to tylko argument czasu kompilacji. Jeśli metoda akceptuje a, IEnumerablewówczas nameofpo prostu zwraca „IEnumerable”, podczas gdy rzeczywistym obiektem może być „List <łańcuch znaków”. Wydaje się, że nie odpowiada na pytanie PO.
— Nigel Touch

-2

najlepszy sposób użycia:

obj.GetType().BaseType.Name

1
Podaj wyjaśnienie swojej odpowiedzi, aby było bardziej zrozumiałe dla innych użytkowników.
— Stanislav Mekhonoshin

Kiedyś znalazłem „GetType (). Name” właśnie napisane tak w funkcji wirtualnej. Czy ktoś może mi wyjaśnić, dlaczego nie ma obj.GetType (). BaseType.Name? Uczę się. Rozumiem cel, ale nie wszystkie szczegóły składni. Dziękuję Ci.
— Diego Orellana,

Co ma z tym wspólnego typ podstawowy?
— Johnny 5

Mój test obj.GetType().BaseType.Namepowraca, "TypeInfo"co nie jest pożądanym rozwiązaniem, jak się spodziewam.
— Nasenbaer
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.