Apakah refleksi dalam C#
menawarkan cara untuk menentukan apakah beberapa System.Type
model yang diberikan beberapa antarmuka?
public interface IMyInterface {}
public class MyType : IMyInterface {}
// should yield 'true'
typeof(MyType)./* ????? */MODELS_INTERFACE(IMyInterface);
c#
reflection
interface
Yippie-Ki-Yay
sumber
sumber
IsAssignableFrom
mundur. Saya akan pergi denganGetInterfaces
sekarang: pIsAssignableFrom(t1)
varian sekitar 3x lebih cepat dariGetInterfaces().Contains(t2)
rekan dalam kode saya.typeof(MyType).GetInterface(nameof(IMyInterface)) != null
untuk jenis keamanan yang lebih baik dan refactoring.Gunakan
Type.IsAssignableFrom
:sumber
atau
sumber
someclass is IMyInterface
karena tidak melibatkan biaya refleksi sama sekali. Jadi, meski tidak salah, itu bukan cara yang ideal untuk melakukannya.is
memeriksa di kedua arah hierarki warisan sedangkanIsAssignableFrom
hanya memeriksa ke atas. Juga, jika Anda memiliki instance objek, Anda harus memanggilIsInstanceOfType
(yang juga hanya melihat ke atas).Saya pikir ini adalah rilis yang benar, karena tiga alasan:
sumber
Saya baru saja melakukannya:
Saya berharap saya bisa mengatakan
where I : interface
, tetapiinterface
bukan opsi kendala parameter generik.class
sedekat yang didapatnya.Pemakaian:
Saya hanya mengatakan
Implements
karena itu lebih intuitif. Saya selaluIsAssignableFrom
jungkir balik.sumber
return typeof(I).IsInterface && typeof(I).IsAssignableFrom(source);
untuk mengembalikan false pada setiap penggunaan metode yang 'salah', yaitu; menggunakannya dengan tipe kelas dan bukan tipe antarmuka, atau melemparkan pengecualian jika tipe-parameter bukan antarmuka. Meskipun Anda bisa berargumen bahwa kelas turunan 'mengimplementasikan' itu orang tua ...Memodifikasi jawaban Jeff untuk kinerja optimal (berkat tes kinerja oleh Pierre Arnaud):
Untuk menemukan semua jenis yang mengimplementasikan antarmuka dalam yang diberikan
Assembly
:sumber
Seperti yang telah disebutkan orang lain: Benjamin 10 Apr '13 pada 22:21 "
Nah, cara lain adalah menciptakan metode ekstensi pendek yang memenuhi, sampai batas tertentu, cara berpikir "paling umum" (dan sepakat bahwa ini adalah pilihan pribadi yang sangat sedikit untuk menjadikannya sedikit "lebih alami" berdasarkan preferensi seseorang. ):
Dan mengapa tidak menjadi sedikit lebih generik (yah tidak yakin apakah itu benar-benar semenarik itu, saya kira saya hanya melewatkan sedikit gula 'sintaksis'):
Saya pikir itu mungkin jauh lebih alami seperti itu, tetapi sekali lagi hanya masalah pendapat yang sangat pribadi:
sumber
Boolean
=>bool
(Saya tidak mengapa saya dulu memiliki beberapa aturan pengkodean "mewah" yang ketat ketika saya masih muda).Jika Anda memiliki tipe atau instance, Anda dapat dengan mudah memeriksa apakah mereka mendukung antarmuka tertentu.
Untuk menguji apakah suatu objek mengimplementasikan antarmuka tertentu:
Untuk menguji apakah suatu tipe mengimplementasikan antarmuka tertentu:
Jika Anda mendapatkan objek generik dan ingin melakukan pemeran serta memeriksa apakah antarmuka yang Anda gunakan untuk mengimplementasikan kode tersebut adalah:
sumber
IsAssignableFrom
sekarang dipindahkan keTypeInfo
:sumber
Siapa pun yang mencari ini mungkin menemukan metode ekstensi berikut berguna:
tes xunit:
sumber
bagaimana dengan
?
sumber
Bagaimana dengan
sumber
Jawaban yang benar adalah
Namun,
mungkin mengembalikan hasil yang salah, seperti yang ditunjukkan kode berikut dengan string dan IConvertible:
Hasil:
sumber
IsAssignableFrom
. Persis seperti yang diperingatkan Benjamin dan Ehouarn.Perhatikan bahwa jika Anda memiliki antarmuka generik
IMyInterface<T>
maka ini akan selalu kembalifalse
:Ini juga tidak bekerja:
Namun, jika
MyType
mengimplementasikanIMyInterface<MyType>
ini berhasil dan mengembalikantrue
:Namun, Anda mungkin tidak akan tahu parameter tipe
T
saat runtime . Solusi yang agak rumit adalah:Solusi Jeff sedikit kurang rapi:
Berikut adalah metode ekstensi
Type
yang berfungsi untuk kasus apa pun:(Perhatikan bahwa di atas menggunakan linq, yang mungkin lebih lambat dari satu loop.)
Anda kemudian dapat melakukan:
sumber