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
インターフェイスを実装したり、クラスから継承したりする場合は、@ snajahiの回答を参照する必要があります。これは、コンパイル時のチェックを使用し、一般的にこの問題に対するより良いアプローチに似ています。
クラスに制約を使用できます。
MyClass<T> where T : Employee
http://msdn.microsoft.com/en-us/library/d5x73970.aspxをご覧ください
コンパイル中に確認したい場合:目的のインターフェイス/クラスを実装して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))
戻り値: と currentが同じ型を表している場合、 current
true
がの継承階層にある場合、 currentがを実装する である場合、またはがジェネリック型パラメーターであり currentが の制約の 1 つを表す場合、またはifは値の型を表し、 currentは( Visual Basic では) を表します。これらの条件がいずれも ではない場合、または である場合。c
Type
Type
c
Type
interface
c
c
Type
c
c
Type
Nullable<c>
Nullable(Of c)
false
true
c
null
If Employee IsAssignableFrom T
then は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のインスタンスから a のインスタンスに文字通り割り当てることができるためです。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->nobase
間違い
と
- 失敗: c1 = b1
- b1 = c1
- 失敗: c2 = b1
- b1 = c2
構文は次のとおりです。typeof(Employee).IsAssignableFrom(typeof(T));
オブジェクトo
がクラスを継承しているか、インターフェイスを実装しているかを判断する別の方法は、 is
andas
演算子を使用することです。
オブジェクトがクラスを継承しているか、インターフェイスを実装しているかのみを知りたい場合、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 の回答を使用してください。