Bagaimana cara mendapatkan nama tipe dari argumen tipe generik?

99

Jika saya memiliki tanda tangan metode seperti

public string myMethod<T>( ... )

Bagaimana saya, di dalam metode, mendapatkan nama tipe yang diberikan sebagai argumen tipe? Saya ingin melakukan sesuatu yang mirip dengan typeof(T).FullName, tetapi itu benar-benar berhasil ...

Tomas Aschan
sumber
10
typeof(T).FullName harus bekerja. Apa yang terjadi?
Nathan Taylor
Saya mendapat kesalahan kompiler pada pernyataan itu - tetapi tampaknya itu disebabkan oleh hal lain, karena sekarang berfungsi. Terima kasih!
Tomas Aschan

Jawaban:

158

Kode Anda harus berfungsi. typeof(T).FullNamesangat valid. Ini adalah program yang berfungsi penuh dan terkompilasi:

using System;

class Program 
{
    public static string MyMethod<T>()
    {
        return typeof(T).FullName;
    }

    static void Main(string[] args)
    {
        Console.WriteLine(MyMethod<int>());

        Console.ReadKey();
    }

}

Menjalankan cetakan di atas (seperti yang diharapkan):

System.Int32
Reed Copsey
sumber
Pastikan untuk mengujinya dengan MyMethod <int>> () dan lihat apa yang Anda dapatkan ... Anda harus memperhitungkan jenis nullable jika Anda peduli dengan jenis yang mendasari dalam skenario itu.
GR7
1
Maksud Anda " <int?>" Jika demikian, itu berhasil, tetapi Anda mendapatkan System.Nullable<int>(dalam sintaks nama lengkap), yang Anda harapkan ...
Reed Copsey
Meskipun saya sudah memiliki solusinya (meskipun tidak berhasil karena suatu alasan ...), saya akan memberi Anda poin perwakilan untuk menulis jawaban terbaik sejauh ini =)
Tomas Aschan
1
Ini hanya membantu saya karena saya berasumsi nameof(T)dan typeof(T).Nameakan melakukan hal yang sama. Ternyata nameof(T)baru saja kembali T.
dahvyd
5

typeof(T).Namedan typeof(T).FullNamebekerja untuk saya. Saya mendapatkan tipe yang disahkan sebagai argumen.

GR7
sumber
1
ah. Jika tipe yang Anda berikan adalah Nullable, untuk mendapatkan tipe yang mendasarinya Anda harus menggunakan sesuatu seperti typeof (T) .GetGenericArguments () [0]
GR7
untuk memeriksa apakah tipe jika nullable, Anda akan menggunakan typeof (T) .IsGenericType, dan jika ya, Anda akan menggunakan yang berikut ini untuk mendapatkan Name atau FUllName ((Type) typeof (T) .GetGenericArguments () [0 ]). Nama
GR7
1

Dengan asumsi Anda memiliki beberapa contoh T yang tersedia, itu tidak berbeda dari tipe lainnya.

var t = new T();

var name = t.GetType().FullName;
womp
sumber
2
Anda bahkan tidak memerlukan turunan dari T .... typeof (T) berfungsi dengan baik tanpa contoh ... Milik Anda akan memberikan perilaku yang berbeda jika subkelas dilewatkan ke dalam metode (sebagai argumen) ..
Reed Copsey
1
Masalah dengan kode itu adalah jika T tidak memiliki konstruktor tanpa parameter maka ia tidak akan berfungsi.
Nathan Taylor
@ Nathan - itu hanya contoh untuk menunjukkan mendapatkan contoh T. Mungkin dengan metode umum dia akan memiliki beberapa jenis T tersedia. @Reed - Anda benar tentu saja, saya berasumsi itulah yang dia kejar.
womp
Masalah lain adalah dalam kasus T adalah kelas abstrak atau antarmuka - kode di atas tidak akan berfungsi. Jika ada batasan tipe generik ("di mana") maka kode jenis ini dapat aman karena kita mengetahui konstruktornya dan mungkin memiliki alasan untuk membuat instance tipe tersebut. Selain itu instantiation boros.
Andrew