有没有办法测试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
实现某个接口或继承自某个类,则应选择@snajahi的答案,该答案使用编译时检查来实现,并通常类似于更好的解决此问题的方法。T
被限制为一些其他类型TOther
时,执行时typeof(T)
实际上会评估为typeof(TOther)
而不是你传递的任何类型T
,在这种情况下,假设TOther
没有实现SomeInterface
, typeof(SomeInterface).IsAssignableFrom(typeof(T))
将会失败,即使你的具体类型确实实现了SomeInterface
。 - Dave CousineauTypeInfo
类的 IsAssignableFrom
方法只接受 TypeInfo
作为其唯一参数,因此示例应该如下所示:
typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())
- To KaMyClass<T> where T : Employee
如果您想在编译期间进行检查:如果 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))
返回值:如果
c
和当前的Type
表示相同的类型,或者当前的Type
在c
的继承层次结构中,或者当前的Type
是c
实现的一个接口,或者c
是一个通用类型参数并且当前的Type
表示 c 的约束之一,或者c
表示一个值类型并且当前的Type
表示Nullable<c>
(Nullable(Of c)
在Visual Basic中)。如果这些条件都不成立,或者c
是null
,则为false
。
如果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 {}
HorizontalRun
和 Dump
)void Main()
{
// https://dev59.com/B2gv5IYBdhLWcg3wSe0f
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
True
child1->baseclass
False
baseclass->child1
True
child2->baseclass
False
baseclass->child2
True
nobase->baseclass
False
baseclass->nobase
False
和
- 失败:c1 = b1
- b1 = c1
- 失败:c2 = b1
- b1 = c2
我相信语法是:typeof(Employee).IsAssignableFrom(typeof(T));
判断一个对象 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 的答案。虽然像其他人所说的那样,IsAssignableFrom是最好的方法,但如果你只需要检查一个类是否继承自另一个类,typeof(T).BaseType == typeof(SomeClass)
也可以胜任。
SomeClass
并非直接派生自BaseClass
。 - Suncat2000