Ma odbicie w C#
ofercie taki sposób, aby ustalić, czy niektórych podanych System.Type
modeli typu jakiś interfejs?
public interface IMyInterface {}
public class MyType : IMyInterface {}
// should yield 'true'
typeof(MyType)./* ????? */MODELS_INTERFACE(IMyInterface);
c#
reflection
interface
Yippie-Ki-Yay
źródło
źródło
IsAssignableFrom
wstecz. PójdęGetInterfaces
teraz: pIsAssignableFrom(t1)
Wariant jest około 3x szybciej niżGetInterfaces().Contains(t2)
odpowiednik w moim kodu.typeof(MyType).GetInterface(nameof(IMyInterface)) != null
dla lepszego bezpieczeństwa typu i refaktoryzacji.Użyj
Type.IsAssignableFrom
:źródło
lub
źródło
someclass is IMyInterface
że w ogóle nie pociąga to za sobą kosztów refleksji. Chociaż nie jest to złe, nie jest to idealny sposób na zrobienie tego.is
sprawdza w obu kierunkach hierarchii dziedziczenia, aIsAssignableFrom
tylko w górę. Ponadto, jeśli masz instancję obiektu, powinieneś wywołaćIsInstanceOfType
(która również patrzy tylko w górę).Wydaje mi się, że jest to prawidłowe wydanie z trzech powodów:
źródło
Właśnie zrobiłem:
Chciałbym móc powiedzieć
where I : interface
, aleinterface
nie jest to ogólna opcja ograniczenia parametru.class
jest tak blisko, jak to możliwe.Stosowanie:
Właśnie powiedziałem,
Implements
ponieważ jest to bardziej intuicyjne. Zawsze dostajęIsAssignableFrom
klapki.źródło
return typeof(I).IsInterface && typeof(I).IsAssignableFrom(source);
zwrócić wartość false w przypadku każdego „nieprawidłowego” użycia metody, to znaczy; używając go z typem klasy zamiast z typem interfejsu, alternatywnie wyrzuć wyjątek, jeśli parametr typu nie jest interfejsem. Chociaż można argumentować, że klasa pochodna „implementuje” jej rodzica ...Modyfikacja odpowiedzi Jeffa w celu uzyskania optymalnej wydajności (dzięki testowi wydajności przeprowadzonemu przez Pierre'a Arnauda):
Aby znaleźć wszystkie typy, które implementują interfejs w danym
Assembly
:źródło
Jak ktoś już wspomniał: Benjamin, 10 kwietnia o godz. 22:21 "
Cóż, innym sposobem jest po prostu stworzenie metody krótkiego rozszerzenia, która w pewnym stopniu spełnia „najbardziej typowy” sposób myślenia (i zgodziła się, że jest to bardzo osobisty wybór, aby uczynić go nieco „bardziej naturalnym” w oparciu o własne preferencje ):
I dlaczego nie pójść trochę bardziej ogólnie (cóż, nie jestem pewien, czy to naprawdę tak interesujące, no cóż, zakładam, że właśnie przechodzę kolejną szczyptę cukru „składniowego”):
Myślę, że w ten sposób może być o wiele bardziej naturalne, ale raz jeszcze to kwestia bardzo osobistych opinii:
źródło
Boolean
=>bool
(Nie wiem, dlaczego kiedy byłem młodszy, miałem jakieś „wymyślne” zasady kodowania).Jeśli masz typ lub instancję, możesz łatwo sprawdzić, czy obsługują one określony interfejs.
Aby sprawdzić, czy obiekt implementuje określony interfejs:
Aby sprawdzić, czy typ implementuje określony interfejs:
Jeśli masz obiekt ogólny i chcesz wykonać rzut, a także sprawdzić, czy interfejs, na który rzutujesz, jest zaimplementowany, kod jest następujący:
źródło
IsAssignableFrom
został teraz przeniesiony doTypeInfo
:źródło
Każdy, kto tego szuka, może uznać następującą metodę rozszerzenia:
testy Xunit:
źródło
co powiesz na
?
źródło
Co powiesz na
źródło
Prawidłowa odpowiedź to
Jednak,
może zwrócić niepoprawny wynik, ponieważ poniższy kod pokazuje łańcuch i IConvertible:
Wyniki:
źródło
IsAssignableFrom
. Tak jak ostrzegają Benjamin i Ehouarn.Pamiętaj, że jeśli masz ogólny interfejs,
IMyInterface<T>
to zawsze zwrócifalse
:To też nie działa:
Jeśli jednak
MyType
implementujeIMyInterface<MyType>
to działa i zwracatrue
:Prawdopodobnie jednak nie będziesz znać parametru typu
T
w czasie wykonywania . Nieco hackerskim rozwiązaniem jest:Rozwiązanie Jeffa jest nieco mniej hackerskie:
Oto metoda rozszerzenia,
Type
która działa w każdym przypadku:(Zauważ, że powyższe używa linq, który prawdopodobnie jest wolniejszy niż pętla.)
Następnie możesz wykonać:
źródło