Załóżmy następujące definicje typów:
public interface IFoo<T> : IBar<T> {}
public class Foo<T> : IFoo<T> {}
Jak dowiedzieć się, czy typ Foo
implementuje ogólny interfejs, IBar<T>
gdy dostępny jest tylko zniekształcony typ?
c#
.net
reflection
sduplooy
źródło
źródło
typeof(IBar<,,,>)
przecinki zachowują się jak symbole zastępczeMusisz przejść przez drzewo dziedziczenia i znaleźć wszystkie interfejsy dla każdej klasy w drzewie, i porównać
typeof(IBar<>)
z wynikiem wywołania,Type.GetGenericTypeDefinition
jeśli interfejs jest ogólny. Z pewnością jest to trochę bolesne.Zobacz tę odpowiedź i te, aby uzyskać więcej informacji i kod.
źródło
źródło
Jako rozszerzenie metody pomocniczej
Przykładowe użycie:
źródło
Używam nieco prostszej wersji metody rozszerzenia @GenericProgrammers:
Stosowanie:
źródło
Musisz sprawdzić w stosunku do skonstruowanego typu interfejsu ogólnego.
Będziesz musiał zrobić coś takiego:
ponieważ
IBar<String>
reprezentuje ten skonstruowany typ. Powodem, dla którego musisz to zrobić, jest to, że jeśli nieT
jest zdefiniowany w czeku, kompilator nie wie, czy masz na myśliIBar<Int32>
czyIBar<SomethingElse>
.źródło
Aby całkowicie poradzić sobie z systemem typów, myślę, że musisz poradzić sobie z rekurencją, np
IList<T>
.ICollection<T>
::IEnumerable<T>
, bez której nie wiedziałbyś, żeIList<int>
ostatecznie się implementujeIEnumerable<>
.źródło
Po pierwsze
public class Foo : IFoo<T> {}
nie kompiluje się, ponieważ musisz podać klasę zamiast T, ale zakładając, że robisz coś podobnegopublic class Foo : IFoo<SomeClass> {}
to jeśli to zrobisz
źródło
Jeśli chciałeś metody rozszerzenia, która obsługiwałaby ogólne typy podstawowe oraz interfejsy, rozwinąłem odpowiedź sduplooy:
źródło
Metoda sprawdzania, czy typ dziedziczy lub implementuje typ ogólny:
źródło
Wypróbuj następujące rozszerzenie.
Aby to przetestować. Stwórz
i metoda testowa
źródło
Nie powinno być nic złego, co następuje:
Aby uzyskać dodatkowy kredyt, możesz złapać wyjątek AmbiguousMatchException, jeśli chcesz podać konkretny parametr typu ogólnego w zapytaniu IBar.
źródło
bool implementsGeneric = (anObject.Implements(typeof(IBar<>).Name) != null);