powinieneś zaktualizować swoją odpowiedź przykładem, np. typeof (T) .IsAssignableFrom (typeof (IMyInterface))
Dr Andrew Burnett-Thompson
Nie skończone nikeee; stara odpowiedź wciąż istnieje. :) Zajęło mi kilka sekund, aby dowiedzieć się, co jest nie tak. W każdym razie +1, znowu fajna funkcja frameworka .net.
Samuel
W rzeczywistości sposób, w jaki wspominasz, jest taki, jaki miałem jakiś czas temu. Poprawiłem ten. Zobacz poprzednie komentarze. T inherits Ufaktycznie przekłada się na typeof(T).IsAssignableFrom(typeof(U)).
nikeee
3
Chociaż to prawie działa, istnieje problem polegający na tym, że jeśli Tjest ograniczony do innego typu TOther, to po wykonaniu w typeof(T)rzeczywistości zostanie oszacowany, typeof(TOther)a nie typ T, który faktycznie przeszedłeś, iw takim przypadku typeof(SomeInterface).IsAssignableFrom(typeof(T))zakończy się niepowodzeniem (zakładając, TOtherże również nie implementuje SomeInterface), nawet jeśli twój konkretny typ zaimplementował SomeInterface.
Dave Cousineau
1
W NET rdzenia IsAssignableFromz TypeInfoklasy przyjmuje tylko TypeInfo jak to tylko argumentu więc próbki powinny być następujące:typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())
Jeśli chcesz sprawdzić podczas kompilacji: Błąd, jeśli TNIE implementuje żądanego interfejsu / klasy, możesz użyć następującego ograniczenia
publicvoidMyRestrictedMethod<T>() where T : MyInterface1, MyInterface2, MySuperClass
{
//Code of my method here, clean without any check for type constraints.
}
Wartość zwracana:true jeśli ca prąd Typereprezentują ten sam typ, lub jeśli obecny Typejest w hierarchii dziedziczenia c, lub jeśli obecny Typejest interface, że cnarzędzia, czy cto ogólny parametr typu i obecny Typestanowi jedno z ograniczeń club if creprezentuje typ wartości, a bieżący Typereprezentuje Nullable<c>( Nullable(Of c)w Visual Basic). falsejeśli żaden z tych warunków nie jest spełniony truelub jeśli ctak null.
Jeśli Employee IsAssignableFrom Tto Tdziedziczy z Employee.
Użycie
typeof(T).IsAssignableFrom(typeof(Employee))
zwraca truetylko wtedy, gdy albo
Ti Employeereprezentują ten sam typ; lub,
Employeedziedziczy z T.
Może to być zamierzone użycie w niektórych przypadkach, ale w przypadku pierwotnego pytania (i bardziej powszechnego użycia), aby określić, kiedy Tdziedziczy lub implementuje niektóre class/ interface, użyj:
ponieważ możesz dosłownie przypisać z instancji a DerivedTypedo instancji a BaseType:
DerivedType childInstance = new DerivedType();
BaseType parentInstance = childInstance; // okay, assigning base from derived
childInstance = (DerivedType) parentInstance; // not okay, assigning derived from base
Chociaż IsAssignableFrom jest najlepszym sposobem, jak powiedzieli inni, jeśli potrzebujesz tylko sprawdzić, czy klasa dziedziczy po innej, również typeof(T).BaseType == typeof(SomeClass)wykonuje zadanie.
To działa, chyba że SomeClassnie pochodzi bezpośrednio z BaseClass.
Suncat2000
0
Alternatywnymi sposobami stwierdzenia, czy obiekt odziedziczy klasę lub implementuje interfejs, jest użycie isias operatorów .
Jeśli chcesz wiedzieć tylko, czy obiekt dziedziczy klasę lub implementuje interfejs, isoperator zwróci wynik boolowski:
bool isCompatibleType = (o is BaseType || o is IInterface);
Jeśli po teście chcesz użyć dziedziczonej klasy lub zaimplementowanego interfejsu, asoperator wykona bezpieczne rzutowanie, zwracając odwołanie do odziedziczonej klasy lub zaimplementowanego interfejsu, jeśli jest zgodny lub zerowy, jeśli nie jest zgodny:
BaseType b = o as BaseType; // Null if d does not inherit from BaseType.
IInterface i = o as IInterface; // Null if d does not implement IInterface.
Odpowiedzi:
Istnieje metoda o nazwie Type.IsAssignableFrom () .
Aby sprawdzić, czy
T
dziedziczy / implementujeEmployee
:typeof(Employee).IsAssignableFrom(typeof(T));
Jeśli kierujesz .NET Core, metoda została przeniesiona do TypeInfo:
typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())
źródło
T inherits U
faktycznie przekłada się natypeof(T).IsAssignableFrom(typeof(U))
.T
jest ograniczony do innego typuTOther
, to po wykonaniu wtypeof(T)
rzeczywistości zostanie oszacowany,typeof(TOther)
a nie typT
, który faktycznie przeszedłeś, iw takim przypadkutypeof(SomeInterface).IsAssignableFrom(typeof(T))
zakończy się niepowodzeniem (zakładając,TOther
że również nie implementujeSomeInterface
), nawet jeśli twój konkretny typ zaimplementowałSomeInterface
.IsAssignableFrom
zTypeInfo
klasy przyjmuje tylko TypeInfo jak to tylko argumentu więc próbki powinny być następujące:typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())
Możesz użyć ograniczeń w klasie.
MyClass<T> where T : Employee
Spójrz na http://msdn.microsoft.com/en-us/library/d5x73970.aspx
źródło
Jeśli chcesz sprawdzić podczas kompilacji: Błąd, jeśli
T
NIE implementuje żądanego interfejsu / klasy, możesz użyć następującego ograniczeniapublic void MyRestrictedMethod<T>() where T : MyInterface1, MyInterface2, MySuperClass { //Code of my method here, clean without any check for type constraints. }
Mam nadzieję że to pomogło.
źródło
Prawidłowa składnia to
typeof(Employee).IsAssignableFrom(typeof(T))
Dokumentacja
źródło
Wyjaśnienie
Jeśli
Employee IsAssignableFrom T
toT
dziedziczy zEmployee
.Użycie
typeof(T).IsAssignableFrom(typeof(Employee))
zwraca
true
tylko wtedy, gdy alboT
iEmployee
reprezentują ten sam typ; lub,Employee
dziedziczy zT
.Może to być zamierzone użycie w niektórych przypadkach, ale w przypadku pierwotnego pytania (i bardziej powszechnego użycia), aby określić, kiedy
T
dziedziczy lub implementuje niektóreclass
/interface
, użyj:typeof(Employee).IsAssignableFrom(typeof(T))
źródło
Wszyscy tak naprawdę mają na myśli:
typeof(BaseType).IsAssignableFrom(typeof(DerivedType)) // => true
ponieważ możesz dosłownie przypisać z instancji a
DerivedType
do instancji aBaseType
:DerivedType childInstance = new DerivedType(); BaseType parentInstance = childInstance; // okay, assigning base from derived childInstance = (DerivedType) parentInstance; // not okay, assigning derived from base
gdy
public class BaseType {} public class DerivedType : BaseType {}
I kilka konkretnych przykładów, jeśli masz problem ze zrozumieniem tego:
(przez LinqPad, stąd
HorizontalRun
iDump
)void Main() { // http://stackoverflow.com/questions/10718364/check-if-t-inherits-or-implements-a-class-interface var b1 = new BaseClass1(); var c1 = new ChildClass1(); var c2 = new ChildClass2(); var nb = new nobase(); Util.HorizontalRun( "baseclass->baseclass,child1->baseclass,baseclass->child1,child2->baseclass,baseclass->child2,nobase->baseclass,baseclass->nobase", b1.IsAssignableFrom(typeof(BaseClass1)), c1.IsAssignableFrom(typeof(BaseClass1)), b1.IsAssignableFrom(typeof(ChildClass1)), c2.IsAssignableFrom(typeof(BaseClass1)), b1.IsAssignableFrom(typeof(ChildClass2)), nb.IsAssignableFrom(typeof(BaseClass1)), b1.IsAssignableFrom(typeof(nobase)) ).Dump("Results"); var results = new List<string>(); string test; test = "c1 = b1"; try { c1 = (ChildClass1) b1; results.Add(test); } catch { results.Add("FAIL: " + test); } test = "b1 = c1"; try { b1 = c1; results.Add(test); } catch { results.Add("FAIL: " + test); } test = "c2 = b1"; try { c2 = (ChildClass2) b1; results.Add(test); } catch { results.Add("FAIL: " + test); } test = "b1 = c2"; try { b1 = c2; results.Add(test); } catch { results.Add("FAIL: " + test); } results.Dump(); } // Define other methods and classes here public static class exts { public static bool IsAssignableFrom<T>(this T entity, Type baseType) { return typeof(T).IsAssignableFrom(baseType); } } class BaseClass1 { public int id; } class ChildClass1 : BaseClass1 { public string name; } class ChildClass2 : ChildClass1 { public string descr; } class nobase { public int id; public string name; public string descr; }
Wyniki
i
źródło
Uważam, że składnia to:
typeof(Employee).IsAssignableFrom(typeof(T));
źródło
Chociaż IsAssignableFrom jest najlepszym sposobem, jak powiedzieli inni, jeśli potrzebujesz tylko sprawdzić, czy klasa dziedziczy po innej, również
typeof(T).BaseType == typeof(SomeClass)
wykonuje zadanie.źródło
SomeClass
nie pochodzi bezpośrednio zBaseClass
.Alternatywnymi sposobami stwierdzenia, czy obiekt
o
dziedziczy klasę lub implementuje interfejs, jest użycieis
ias
operatorów .Jeśli chcesz wiedzieć tylko, czy obiekt dziedziczy klasę lub implementuje interfejs,
is
operator zwróci wynik boolowski:bool isCompatibleType = (o is BaseType || o is IInterface);
Jeśli po teście chcesz użyć dziedziczonej klasy lub zaimplementowanego interfejsu,
as
operator wykona bezpieczne rzutowanie, zwracając odwołanie do odziedziczonej klasy lub zaimplementowanego interfejsu, jeśli jest zgodny lub zerowy, jeśli nie jest zgodny:BaseType b = o as BaseType; // Null if d does not inherit from BaseType. IInterface i = o as IInterface; // Null if d does not implement IInterface.
Jeśli masz tylko typ
T
, użyj odpowiedzi @ nikeee.źródło