106

T がクラス/インターフェースを継承/実装しているかどうかをテストする方法はありますか?

private void MyGenericClass<T> ()
{
    if(T ... inherits or implements some class/interface
}
4

8 に答える 8

155

Type.IsAssignableFrom()というメソッドがあります。

T継承/実装するかどうかを確認するにはEmployee

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

.NET Coreを対象としている場合、メソッドはTypeInfoに移動しました。

typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).Ge‌​tTypeInfo())

タイプを制約してTインターフェイスを実装したり、クラスから継承したりする場合は、@ snajahiの回答を参照する必要があります。これは、コンパイル時のチェックを使用し、一般的にこの問題に対するより良いアプローチに似ています。

于 2012-05-23T10:50:55.760 に答える
36

クラスに制約を使用できます。

MyClass<T> where T : Employee

http://msdn.microsoft.com/en-us/library/d5x73970.aspxをご覧ください

于 2012-05-23T10:46:35.120 に答える
19

コンパイル中に確認したい場合:目的のインターフェイス/クラスを実装してT いない場合にエラーが発生する場合は、次の制約を使用できます。

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

それが役立つことを願っています。

于 2014-03-27T12:31:21.757 に答える
13

正しい構文は次のとおりです。

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

ドキュメンテーション

戻り値: と currentが同じ型を表している場合、 currenttrueがの継承階層にある場合、 currentがを実装する である場合、またはがジェネリック型パラメーターであり currentが の制約の 1 つを表す場合、またはifは値の型を表し、 currentは( Visual Basic では) を表します。これらの条件がいずれも ではない場合、または である場合。cTypeTypecTypeinterfaceccTypeccTypeNullable<c>Nullable(Of c)falsetruecnull

ソース

説明

If Employee IsAssignableFrom Tthen はTから継承しEmployeeます。

使い方

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

次のいずれかの場合にtrue のみ戻ります

  1. TおよびEmployee同じタイプを表します。また、
  2. Employeeから継承しTます。

これは場合によっては意図した使用法かもしれません、元の質問 (およびより一般的な使用法) では、/をいつT継承または実装するかを判断するには、次を使用します。classinterface

typeof(Employee).IsAssignableFrom(typeof(T))
于 2014-07-29T14:49:48.043 に答える
11

誰もが本当に意味することは次のとおりです。

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

aのインスタンスから a のインスタンスに文字通り割り当てることができるためです。DerivedTypeBaseType

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 経由、したがってHorizontalRunDump)

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;
}

結果

ベースクラス -> ベースクラス

真実

child1->基本クラス

間違い

baseclass->child1

真実

child2->基本クラス

間違い

baseclass->child2

真実

nobase->基本クラス

間違い

baseclass->nobase

間違い

  • 失敗: c1 = b1
  • b1 = c1
  • 失敗: c2 = b1
  • b1 = c2
于 2015-11-25T17:46:33.963 に答える
2

構文は次のとおりです。typeof(Employee).IsAssignableFrom(typeof(T));

于 2014-06-17T20:29:51.083 に答える
0

オブジェクトoがクラスを継承しているか、インターフェイスを実装しているかを判断する別の方法は、 isandas演算子を使用することです。

オブジェクトがクラスを継承しているか、インターフェイスを実装しているかのみを知りたい場合、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.

type しかない場合はT、@nikeee の回答を使用してください。

于 2019-04-25T21:18:11.897 に答える