Вопрос по c#, generics – Проверьте, если T наследует или реализует класс / интерфейс

75

Есть ли способ проверить, если T наследует / реализует класс / интерфейс?

private void MyGenericClass<T> ()
{
    if(T ... inherits or implements some class/interface
}
это похоже на работу ... if (typeof (TestClass) .IsAssignableFrom (typeof (T))), кто-то может подтвердить мои подозрения? Благодарность user1229895
Я абсолютно уверен, что этот ответ дублируется много раз! Felix K.
Да, это сработает. Oliver
Felix K Даже если этот ответ дублировался много раз, он также помогает многим парням много раз;) ... как я пять минут назад:) Samuel

Ваш Ответ

7   ответов
29

Вы можете использовать ограничения для класса.

MyClass<T> where T : Employee

Взгляни наhttp: //msdn.microsoft.com/en-us/library/d5x73970.asp

101

Type.IsAssignableFrom ().

ПроверитьT наследует / реализуетEmployee:

typeof(Employee).IsAssignableFrom(typeof(T));

Если вы ориентируетесь на .NET Core, метод переместился в TypeInfo:

typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).Ge‌​tTypeInfo())
Вы должны обновить свой ответ, например, например. TypeOf (Т) .IsAssignableFrom (TypeOf (IMyInterface)) Dr. ABT
О, моя вина. Выполнено nikeee
Хотя это почти работает, есть проблема, еслиT ограничен другим типомTOther, затем при исполненииtypeof(T) на самом деле оценивается какtypeof(TOther) а не типаT ты на самом деле прошел, и в этом случае,typeof(SomeInterface).IsAssignableFrom(typeof(T)) не удастся (при условииTOther также не реализуетSomeInterface), хотя ваш конкретный тип реализовалSomeInterface. Dave Cousineau
Синтаксис неверен, см. Ответ ниже. Chalky
In .net coreIsAssignableFrom ofTypeInfo class принимает только TypeInfo в качестве единственного аргумента, поэтому пример должен быть следующим:typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()) To Ka
11

Ошибка, если еслиT н реализовать желаемый интерфейс / класс, вы можете использовать следующее ограничение

public void MyRestrictedMethod<T>() where T : MyInterface1, MyInterface2, MySuperClass
{
    //Code of my method here, clean without any check for type constraints.
}

Надеюсь, это поможет

8

Правильный синтаксис:

typeof(Employee).IsAssignableFrom(typeof(T))
Документаци

Возвращаемое значение: true еслиc и текущийType представляют тот же тип, или если текущийType находится в иерархии наследованияc, или если текущийType являетсяinterface чтоc реализует, или еслиc - это параметр общего типа и текущийType представляет собой одно из ограниченийc, или если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.

Это может быть предназначено для использования внескольк case, но для исходного вопроса (и более распространенного использования), чтобы определить, когдаT наследует или реализует некоторыеclass/interface, используйте:

typeof(Employee).IsAssignableFrom(typeof(T))
2

typeof(Employee).IsAssignableFrom(typeof(T));

Это предполагаемый синтаксис. + 1 Luke M Willis
7

typeof(BaseType).IsAssignableFrom(typeof(DerivedType)) // => true

потому что ты можешь буквальноassign от экземплярDerivedType к экземпляруBaseType:

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;
}
Полученные результат

Baseclass-> BaseClass

Правд

Child1-> BaseClass

Лож

Baseclass-> child1

Правд

Child2-> BaseClass

Лож

Baseclass-> child2

Правд

Nobase-> BaseClass

Лож

Baseclass-> nobase

Лож

а такж

FAIL: c1 = b1 b1 = c1FAIL: c2 = b1 b1 = c2
0

как заявили другие, если вам нужно только проверить, наследует ли класс другой,typeof(T).BaseType == typeof(SomeClass) тоже выполняет свою работу.

Похожие вопросы