Asumsikan definisi tipe berikut:
public interface IFoo<T> : IBar<T> {}
public class Foo<T> : IFoo<T> {}
Bagaimana cara mengetahui apakah tipe Foo
mengimplementasikan antarmuka generik IBar<T>
ketika hanya tipe yang rusak tersedia?
c#
.net
reflection
sduplooy
sumber
sumber
typeof(IBar<,,,>)
dengan koma yang bertindak seperti placeholderAnda harus naik melalui pohon warisan dan menemukan semua antarmuka untuk setiap kelas di pohon, dan bandingkan
typeof(IBar<>)
dengan hasil pemanggilanType.GetGenericTypeDefinition
jika antarmuka generik. Ini semua agak menyakitkan, tentu saja.Lihat jawaban ini dan yang ini untuk info dan kode lebih lanjut.
sumber
sumber
Sebagai perpanjangan metode penolong
Contoh penggunaan:
sumber
Saya menggunakan metode ekstensi @GenericProgrammers versi yang sedikit lebih sederhana:
Pemakaian:
sumber
Anda harus memeriksa jenis antarmuka generik yang dikonstruksi.
Anda harus melakukan sesuatu seperti ini:
karena
IBar<String>
mewakili tipe yang dikonstruksi. Alasan Anda harus melakukan ini adalah karena jikaT
tidak ditentukan dalam pemeriksaan Anda, kompiler tidak tahu apakah maksud AndaIBar<Int32>
atauIBar<SomethingElse>
.sumber
Untuk mengatasi sistem jenis yang sama sekali, saya pikir Anda perlu menangani rekursi, misalnya
IList<T>
:ICollection<T>
:IEnumerable<T>
, tanpa yang Anda tidak akan tahu bahwaIList<int>
pada akhirnya mengimplementasikanIEnumerable<>
.sumber
Pertama-tama
public class Foo : IFoo<T> {}
tidak dikompilasi karena Anda perlu menentukan kelas, bukan T, tetapi dengan asumsi Anda melakukan sesuatu sepertipublic class Foo : IFoo<SomeClass> {}
maka jika Anda melakukannya
sumber
Jika Anda menginginkan metode ekstensi yang akan mendukung tipe dasar umum serta antarmuka, saya telah memperluas jawaban sduplooy:
sumber
Metode untuk memeriksa apakah tipe tersebut mewarisi atau mengimplementasikan tipe generik:
sumber
Coba ekstensi berikut.
Untuk mengujinya. membuat
dan metode pengujian
sumber
Seharusnya tidak ada yang salah berikut ini:
Untuk kredit tambahan, Anda dapat menangkap AmbiguousMatchException jika Anda ingin memberikan parameter tipe-generik tertentu dengan kueri IBar Anda.
sumber
bool implementsGeneric = (anObject.Implements(typeof(IBar<>).Name) != null);