apakah ada cara untuk mengambil tipe T
dari IEnumerable<T>
melalui refleksi?
misalnya
saya punya IEnumerable<Child>
info variabel ; Saya ingin mendapatkan kembali tipe Child melalui refleksi
c#
generics
reflection
Usman Masood
sumber
sumber
Jawaban:
Demikian,
cetakan
System.String
.Lihat MSDN untuk
Type.GetGenericArguments
.Sunting: Saya yakin ini akan mengatasi masalah di komentar:
Beberapa objek mengimplementasikan lebih dari satu generik
IEnumerable
sehingga perlu mengembalikan enumerasi mereka.Sunting: Meskipun, saya harus mengatakan, itu adalah ide yang buruk bagi kelas untuk diterapkan
IEnumerable<T>
lebih dari satuT
.sumber
Saya baru saja membuat metode ekstensi. Ini bekerja dengan semua yang saya lemparkan.
sumber
Saya memiliki masalah serupa. Jawaban yang dipilih berfungsi untuk contoh aktual. Dalam kasus saya, saya hanya memiliki tipe (dari a
PropertyInfo
).Jawaban yang dipilih gagal ketika tipe itu sendiri
typeof(IEnumerable<T>)
bukan merupakan implementasi dariIEnumerable<T>
.Untuk kasus ini pekerjaan berikut:
sumber
Type.GenericTypeArguments
- hanya untuk dotNet FrameWork versi> = 4.5. Jika tidak - gunakanType.GetGenericArguments
saja.Jika Anda tahu
IEnumerable<T>
(melalui generik), makatypeof(T)
seharusnya berfungsi. Jika tidak (untukobject
, atau non-generikIEnumerable
), periksa antarmuka yang diterapkan:sumber
Type type
parameter daripadaobject obj
parameter: Anda tidak bisa hanya menggantiobj.GetType()
dengantype
karena jika Anda meneruskantypeof(IEnumerable<T>)
Anda tidak mendapatkan apa-apa. Untuk mengatasi ini, ujitype
dirinya sendiri untuk melihat apakah itu generikIEnumerable<>
dan kemudian antarmukanya.Terima kasih banyak atas pembahasannya. Saya menggunakannya sebagai dasar untuk solusi di bawah ini, yang berfungsi dengan baik untuk semua kasus yang menarik bagi saya (IEnumerable, kelas turunan, dll). Saya pikir saya harus berbagi di sini jika ada yang membutuhkannya juga:
sumber
someCollection.GetType().GetInterface(typeof(IEnumerable<>).Name)?.GetGenericArguments()?.FirstOrDefault()
Gunakan saja
typeof(T)
EDIT: Atau gunakan .GetType (). GetGenericParameter () pada objek yang dibuat jika Anda tidak memiliki T.
sumber
Alternatif untuk situasi yang lebih sederhana di mana itu akan menjadi
IEnumerable<T>
atauT
- gunakan catatanGenericTypeArguments
alih-alihGetGenericArguments()
.sumber
Ini adalah perbaikan pada solusi Eli Algranti karena ia juga akan berfungsi di mana
IEnumerable<>
jenisnya berada di tingkat mana pun dalam pohon warisan.Solusi ini akan mendapatkan tipe elemen dari apapun
Type
. Jika tipe bukanIEnumerable<>
, itu akan mengembalikan tipe yang diteruskan. Untuk objek, gunakanGetType
. Untuk jenis, gunakantypeof
, lalu panggil metode ekstensi ini pada hasil.sumber
Saya tahu ini agak lama, tetapi saya yakin metode ini akan mencakup semua masalah dan tantangan yang disebutkan di komentar. Penghargaan untuk Eli Algranti karena telah menginspirasi pekerjaan saya.
sumber
Ini adalah fungsi rekursif yang akan masuk ke dalam daftar tipe generik terlebih dahulu sampai mendapatkan definisi tipe konkret tanpa tipe generik dalam.
Saya menguji metode ini dengan tipe ini:
ICollection<IEnumerable<ICollection<ICollection<IEnumerable<IList<ICollection<IEnumerable<IActionResult>>>>>>>>
yang harus dikembalikan
IActionResult
sumber
typeof(IEnumerable<Foo>)
. akan mengembalikan argumen umum pertama - dalam kasus ini .GetGenericArguments()
[0]
typeof(Foo)
sumber
ini adalah cara saya biasanya melakukannya (melalui metode ekstensi):
sumber
Ini versi ekspresi kueri Linq saya yang tidak dapat dibaca ..
Perhatikan bahwa metode ini juga memperhitungkan non-generik
IEnumerable
, ia mengembalikanobject
dalam kasus ini, karena mengambilType
contoh konkret daripada sebagai argumen. Ngomong-ngomong, karena x mewakili hal yang tidak diketahui , menurut saya video ini menarik , meskipun tidak relevan ..sumber