c#中的反射是否提供了一种方法来确定某个给定的System。类型类型模型一些接口?
public interface IMyInterface {}
public class MyType : IMyInterface {}
// should yield 'true'
typeof(MyType)./* ????? */MODELS_INTERFACE(IMyInterface);
c#中的反射是否提供了一种方法来确定某个给定的System。类型类型模型一些接口?
public interface IMyInterface {}
public class MyType : IMyInterface {}
// should yield 'true'
typeof(MyType)./* ????? */MODELS_INTERFACE(IMyInterface);
当前回答
如果您有一个类型或实例,您可以很容易地检查它们是否支持特定的接口。
测试一个对象是否实现了某个接口:
if(myObject is IMyInterface) {
// object myObject implements IMyInterface
}
测试一个类型是否实现了某个接口:
if(typeof(IMyInterface).IsAssignableFrom(typeof(MyType))) {
// type MyType implements IMyInterface
}
如果你有一个通用对象,想要进行强制转换,并检查你强制转换的接口是否实现,代码如下:
var myCastedObject = myObject as IMyInterface;
if(myCastedObject != null) {
// object myObject implements IMyInterface
}
其他回答
修改Jeff的答案以获得最佳性能(感谢Pierre Arnaud的性能测试):
var type = typeof(MyType);
var implementsInterface = typeof(IMyInterface).IsAssignableFrom(type) && type.IsClass;
查找在给定程序集中实现接口的所有类型:
var implementations = typeof(TypeInTargetAssembly).Assembly.GetTypes()
.Where(t => typeof(IMyInterface).IsAssignableFrom(t) && t.IsClass);
正如其他人已经提到的: 本杰明13年4月10日22:21
这当然很容易让人不注意,并得到争论 IsAssignableFrom倒退。我现在用GetInterfaces:p -
好吧,另一种方法是创建一个简短的扩展方法,在某种程度上,满足“最常见”的思维方式(并且同意这是一个非常小的个人选择,使它稍微“更自然”基于个人的喜好):
public static class TypeExtensions
{
public static bool IsAssignableTo(this Type type, Type assignableType)
{
return assignableType.IsAssignableFrom(type);
}
}
为什么不更通用一点呢(好吧,不确定它是否真的那么有趣,好吧,我假设我只是传递另一个“语法”糖):
public static class TypeExtensions
{
public static bool IsAssignableTo(this Type type, Type assignableType)
{
return assignableType.IsAssignableFrom(type);
}
public static bool IsAssignableTo<TAssignable>(this Type type)
{
return IsAssignableTo(type, typeof(TAssignable));
}
}
我认为这样可能会更自然,但这只是我个人的观点:
var isTrue = michelleType.IsAssignableTo<IMaBelle>();
正确答案是
typeof(MyType).GetInterface(nameof(IMyInterface)) != null;
然而,
typeof(MyType).IsAssignableFrom(typeof(IMyInterface));
可能会返回错误的结果,如下面的代码所示:
static void TestIConvertible()
{
string test = "test";
Type stringType = typeof(string); // or test.GetType();
bool isConvertibleDirect = test is IConvertible;
bool isConvertibleTypeAssignable = stringType.IsAssignableFrom(typeof(IConvertible));
bool isConvertibleHasInterface = stringType.GetInterface(nameof(IConvertible)) != null;
Console.WriteLine($"isConvertibleDirect: {isConvertibleDirect}");
Console.WriteLine($"isConvertibleTypeAssignable: {isConvertibleTypeAssignable}");
Console.WriteLine($"isConvertibleHasInterface: {isConvertibleHasInterface}");
}
结果:
isConvertibleDirect: True
isConvertibleTypeAssignable: False
isConvertibleHasInterface: True
public static bool ImplementsInterface(this Type type, Type ifaceType)
{
Type[] intf = type.GetInterfaces();
for(int i = 0; i < intf.Length; i++)
{
if(intf[ i ] == ifaceType)
{
return true;
}
}
return false;
}
我认为这是一个正确的版本,原因有三:
它使用GetInterfaces而不是IsAssignableFrom,因为它更快 IsAssignableFrom最终在几次检查后调用 getinterface。 它遍历本地数组,所以会有 没有边界检查。 它使用为定义的==操作符 类型,因此可能比Equals方法更安全 调用,将最终使用)。
使用类型。IsAssignableTo(自。net 5.0起):
typeof(MyType).IsAssignableTo(typeof(IMyInterface));
正如在一些评论中所述,IsAssignableFrom可能被认为是“向后”的混淆。