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?)

leora
źródło
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
Tim Robinson
źródło
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>
gregsdennis
źródło
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
9

skorzystaj z ( Właściwości typu )

 Name   Gets the name of the current member. (Inherited from MemberInfo.)
 Example : typeof(T).Name;
Pranay Rana
źródło
5

typeof (T) .Name;

Datoon
źródło
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”.

Staś Bojarincew
źródło
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
Hossein Ebrahimi
źródło
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