вам следует обновить свой ответ примером, например, typeof (T) .IsAssignableFrom (typeof (IMyInterface))
доктор Эндрю Бернетт-Томпсон,
Не сделано никеее; старый ответ все еще существует. :) Мне потребовалась пара секунд, чтобы разобраться, в чем дело. В любом случае, +1, опять же хорошая особенность .net framework.
Самуэль
Фактически, вы упомянули, как это было у меня некоторое время назад. Я исправил это. См. Предыдущие комментарии. T inherits Uфактически переводится как typeof(T).IsAssignableFrom(typeof(U)).
nikeee
3
Хотя это почти работает, существует проблема, когда if Tограничен каким-то другим типом TOther, а затем при выполнении typeof(T)будет фактически оценивать, typeof(TOther)а не тот тип, который Tвы фактически передали, и в этом случае typeof(SomeInterface).IsAssignableFrom(typeof(T))произойдет сбой (при условии, TOtherчто также не реализуется SomeInterface), даже если ваш конкретный тип реализован SomeInterface.
Дэйв Кузино,
1
В .net сердцевины IsAssignableFromиз TypeInfoкласса принимает только TypeInfo , поскольку это единственный аргумент, так что образец должен быть следующим:typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())
Если вы хотите проверить во время компиляции: Ошибка, если if TНЕ реализует желаемый интерфейс / класс, вы можете использовать следующее ограничение
publicvoidMyRestrictedMethod<T>() where T : MyInterface1, MyInterface2, MySuperClass
{
//Code of my method here, clean without any check for type constraints.
}
Возвращаемое значение:true если cи ток Typeпредставляет собой один и тот же тип, или если ток Typeнаходится в иерархии наследования c, или если ток Typeявляется , interfaceчто cорудия, или если cэто общий параметр типа и ток Typeпредставляет собой одно из ограничений c, или if cпредставляет тип значения, а текущий Typeпредставляет Nullable<c>( Nullable(Of c)в Visual Basic). falseесли ни одно из этих условий не выполнено trueили cесть null.
Если Employee IsAssignableFrom Tтогда Tнаследуется от Employee.
Использование
typeof(T).IsAssignableFrom(typeof(Employee))
возвращается trueтолько когда либо
Tи Employeeпредставляют собой однотипные; или,
Employeeнаследуется от T.
В некоторых случаях это может быть предполагаемое использование , но для исходного вопроса (и более распространенного использования), чтобы определить, когда Tнаследует или реализует некоторые class/ interface, используйте:
потому что вы можете буквально назначить экземпляр a DerivedTypeэкземпляру a BaseType:
DerivedType childInstance = new DerivedType();
BaseType parentInstance = childInstance; // okay, assigning base from derived
childInstance = (DerivedType) parentInstance; // not okay, assigning derived from base
Хотя IsAssignableFrom - лучший способ, как заявляли другие, если вам нужно только проверить, наследуется ли класс от другого, typeof(T).BaseType == typeof(SomeClass)тоже выполняет свою работу.
Это работает, если не SomeClassявляется прямым производным от BaseClass.
Suncat2000
0
Альтернативные способы сказать , если объект oнаследует класс или реализует интерфейс для использования isи asоператоров.
Если вы хотите знать, наследует ли объект класс или реализует интерфейс, isоператор вернет логический результат:
bool isCompatibleType = (o is BaseType || o is IInterface);
Если вы хотите использовать унаследованный класс или реализованный интерфейс после теста, asоператор выполнит безопасное преобразование, возвращая ссылку на унаследованный класс или реализованный интерфейс, если он совместим, или null, если он несовместим:
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.
Если у вас есть только тип T, используйте ответ @nikeee.
Ответы:
Существует метод под названием Type.IsAssignableFrom () .
Чтобы проверить,
T
наследует ли / реализуетEmployee
:typeof(Employee).IsAssignableFrom(typeof(T));
Если вы ориентируетесь на .NET Core, метод перемещен в TypeInfo:
typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())
источник
T inherits U
фактически переводится какtypeof(T).IsAssignableFrom(typeof(U))
.T
ограничен каким-то другим типомTOther
, а затем при выполненииtypeof(T)
будет фактически оценивать,typeof(TOther)
а не тот тип, которыйT
вы фактически передали, и в этом случаеtypeof(SomeInterface).IsAssignableFrom(typeof(T))
произойдет сбой (при условии,TOther
что также не реализуетсяSomeInterface
), даже если ваш конкретный тип реализованSomeInterface
.IsAssignableFrom
изTypeInfo
класса принимает только TypeInfo , поскольку это единственный аргумент, так что образец должен быть следующим:typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())
Вы можете использовать ограничения для класса.
MyClass<T> where T : Employee
Взгляните на http://msdn.microsoft.com/en-us/library/d5x73970.aspx
источник
Если вы хотите проверить во время компиляции: Ошибка, если if
T
НЕ реализует желаемый интерфейс / класс, вы можете использовать следующее ограничениеpublic void MyRestrictedMethod<T>() where T : MyInterface1, MyInterface2, MySuperClass { //Code of my method here, clean without any check for type constraints. }
Надеюсь, это поможет.
источник
Правильный синтаксис
typeof(Employee).IsAssignableFrom(typeof(T))
Документация
источник
Объяснение
Если
Employee IsAssignableFrom T
тогдаT
наследуется отEmployee
.Использование
typeof(T).IsAssignableFrom(typeof(Employee))
возвращается
true
только когда либоT
иEmployee
представляют собой однотипные; или,Employee
наследуется отT
.В некоторых случаях это может быть предполагаемое использование , но для исходного вопроса (и более распространенного использования), чтобы определить, когда
T
наследует или реализует некоторыеclass
/interface
, используйте:typeof(Employee).IsAssignableFrom(typeof(T))
источник
На самом деле все имеют в виду:
typeof(BaseType).IsAssignableFrom(typeof(DerivedType)) // => true
потому что вы можете буквально назначить экземпляр a
DerivedType
экземпляру aBaseType
:DerivedType childInstance = new DerivedType(); BaseType parentInstance = childInstance; // okay, assigning base from derived childInstance = (DerivedType) parentInstance; // not okay, assigning derived from base
когда
public class BaseType {} public class DerivedType : BaseType {}
И несколько конкретных примеров, если вам сложно понять это:
(через LinqPad, отсюда
HorizontalRun
иDump
)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; }
Полученные результаты
а также
источник
Я считаю, что синтаксис:
typeof(Employee).IsAssignableFrom(typeof(T));
источник
Хотя IsAssignableFrom - лучший способ, как заявляли другие, если вам нужно только проверить, наследуется ли класс от другого,
typeof(T).BaseType == typeof(SomeClass)
тоже выполняет свою работу.источник
SomeClass
является прямым производным отBaseClass
.Альтернативные способы сказать , если объект
o
наследует класс или реализует интерфейс для использованияis
иas
операторов.Если вы хотите знать, наследует ли объект класс или реализует интерфейс,
is
оператор вернет логический результат:bool isCompatibleType = (o is BaseType || o is IInterface);
Если вы хотите использовать унаследованный класс или реализованный интерфейс после теста,
as
оператор выполнит безопасное преобразование, возвращая ссылку на унаследованный класс или реализованный интерфейс, если он совместим, или null, если он несовместим: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.
Если у вас есть только тип
T
, используйте ответ @nikeee.источник