Tがクラス/インターフェースを継承/実装しているかどうかをテストする方法はありますか?
private void MyGenericClass<T> ()
{
if(T ... inherits or implements some class/interface
}
Tがクラス/インターフェースを継承/実装しているかどうかをテストする方法はありますか?
private void MyGenericClass<T> ()
{
if(T ... inherits or implements some class/interface
}
回答:
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を
正しい構文は
typeof(Employee).IsAssignableFrom(typeof(T))
戻り値:
true
もしc
、電流がType
同じタイプを表し、又は電流が場合Type
の継承階層にあるc
、または現在は次の場合Type
であるinterface
ことc
実装、または場合は、c
ジェネリック型パラメータであり、電流Type
の制約の1つを表しc
、またはifc
は値のタイプを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
使用。
typeof(Employee).IsAssignableFrom(typeof(T))
誰もが本当に意味することは:
typeof(BaseType).IsAssignableFrom(typeof(DerivedType)) // => true
あなたは、文字通りすることができますので、から割り当てるのインスタンス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;
}
ベースクラス->ベースクラス
本当
child1->ベースクラス
誤り
baseclass-> child1
本当
child2->ベースクラス
誤り
baseclass-> child2
本当
nobase-> baseclass
誤り
baseclass-> nobase
誤り
そして
- 失敗:c1 = b1
- b1 = c1
- 失敗:c2 = b1
- b1 = c2
他の人が述べたように、IsAssignableFromが最善の方法ですが、クラスが別のクラスから継承するかどうかを確認するだけでよい場合typeof(T).BaseType == typeof(SomeClass)
は、その仕事も行います。
SomeClass
から直接派生しない限り、これは機能しBaseClass
ます。
オブジェクトo
がクラスを継承しているか、インターフェースを実装しているかを確認する別の方法は、is
and 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の回答を使用してください。