Dapatkan nama tipe tanpa namespace lengkap


293

Saya memiliki kode berikut:

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

Tapi

 typeof(T).ToString()

mengembalikan nama lengkap termasuk namespace

Apakah ada cara untuk mendapatkan nama kelas (tanpa kualifikasi namespace?)


7
Kebetulan, menulis string1 + anything.ToString() + string2itu berlebihan. Kompiler memasukkan panggilan ke ToStringsecara otomatis jika Anda melakukannya string1 + anything + string2.
Tim Robinson 3-10

13
tidak terdengar keras tetapi, sudahkah Anda memeriksa properti apa yang tersedia pada Typecontoh (seperti yang dikembalikan oleh typeof(..)) Saya cukup yakin Anda akan mengetahuinya sendiri ...
Peter Lillevold

Jawaban:


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

5
Nametidak mempertimbangkan parameter tipe.
gregsdennis

73
Atau this.GetType().Name,, this.GetType().FullNamedll. Jika berurusan dengan instance.
lanjut

1
Namejuga tidak mempertimbangkan tipe bersarang!
Simpanse Warlike

33

Coba ini untuk mendapatkan parameter tipe untuk tipe umum:

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

Mungkin bukan solusi terbaik (karena rekursi), tetapi berhasil. Outputnya terlihat seperti:

Dictionary<String, Object>

3
Ini seharusnya menjadi jawaban yang diterima karena dengan tepat mempertimbangkan jenis generik yang dapat muncul kembali (Kamus <int?, Int?> Misalnya).
Otis

+1 untuk konsep. Tetapi tidak menyukai optimasi prematur yang gagal. Ini menciptakan baru StringBuilder dalam setiap panggilan rekursif (bahkan kasus dasar ketika tidak digunakan), namun mengabaikan string.Joinlambda sementara dan LINQ. Cukup gunakan Stringsampai Anda tahu itu hambatan. / kata
Nigel Touch

1
Nigel, katanya di sana itu mungkin bukan solusi terbaik :)
gregsdennis

ShortName adalah nama yang lebih pendek :)
Valera



5

Setelah C # 6.0 (termasuk) Anda dapat menggunakan nama ekspresi:

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  

Catatan! nameoftidak mendapatkan Jenis runtime objek yang mendasarinya, itu hanya argumen waktu kompilasi. Jika suatu metode menerima IEnumerable maka nameof hanya mengembalikan "IEnumerable", sedangkan objek yang sebenarnya bisa menjadi "Daftar".


3
nameoftidak mengembalikan namaType
Nigel Touch

@NigelTouch Saya telah memeriksa dan nameofmengembalikan nama Typetangkapan layar, dengan bukti: prntscr.com/irfk2c
Stas Boyarincev

1
Maaf, saya tidak menjelaskan dengan baik. Maksud saya adalah bahwa ia tidak mendapatkan runtime objek yang mendasarinya Type, itu hanya argumen waktu kompilasi. Jika suatu metode menerima suatu, IEnumerablemaka nameofcukup mengembalikan "IEnumerable", sedangkan objek yang sebenarnya adalah "List <string>". Itu tidak berpikir itu menjawab pertanyaan OP.
Nigel Touch

-2

cara terbaik untuk menggunakan:

obj.GetType().BaseType.Name

1
Harap berikan beberapa penjelasan untuk jawaban Anda, agar lebih jelas bagi pengguna lain.
Stanislav Mekhonoshin

Saya pernah menemukan "GetType (). Name" yang baru saja ditulis seperti itu di dalam fungsi virtual. Dapatkah seseorang menjelaskan kepada saya mengapa tidak memiliki obj.GetType (). BaseType.Name? Aku belajar. Saya mengerti tujuannya tetapi tidak semua detail sintaksis. Terima kasih.
Diego Orellana

Apa hubungannya tipe dasar dengan ini?
johnny 5

obj.GetType().BaseType.NameHasil tes saya kembali "TypeInfo"yang bukan solusi yang diinginkan seperti yang saya harapkan.
Nasenbaer
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.