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

leora
sumber
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
Tim Robinson
sumber
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>
gregsdennis
sumber
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
9

memanfaatkan ( Tipe Properti )

 Name   Gets the name of the current member. (Inherited from MemberInfo.)
 Example : typeof(T).Name;
Pranay Rana
sumber
5

typeof (T) .Nama;

Datoon
sumber
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".

Stas Boyarincev
sumber
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
Hossein Ebrahimi
sumber
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