测试对象是不是实现接口
Posted
技术标签:
【中文标题】测试对象是不是实现接口【英文标题】:Test if object implements interface测试对象是否实现接口 【发布时间】:2010-09-29 10:36:06 【问题描述】:测试对象是否在 C# 中实现给定接口的最简单方法是什么? (回答这个问题 in Java)
【问题讨论】:
【参考方案1】: interface IItem
class ItemImp : IItem
class Program
static void Main(string[] args)
Type t = typeof(ItemImp);
Console.WriteLine("t == typeof(IItem) -> 0", t == typeof(IItem));
Console.WriteLine("typeof(IItem).IsAssignableFrom(t) -> 0", typeof(IItem).IsAssignableFrom(t));
Console.WriteLine("t is IItem -> 0", t is IItem);
Console.WriteLine("new ItemImp() is IItem -> 0", new ItemImp() is IItem);
// Here are outputs:
// t == typeof(IItem) -> False
// typeof(IItem).IsAssignableFrom(t) -> True
// t is IItem -> False
// new ItemImp() is IItem -> True
【讨论】:
如果回答一个老问题,你应该解释为什么你的答案比之前提交的答案更相关。一个例子是注意到 C# 中的更新允许现在完成 x 在过去更复杂的地方。【参考方案2】:我通过使用is
关键字实现了这一点。
但我还需要一个新对象来使用接口属性。 为此,您需要在接口之后添加新变量。
objectToCheck is Interface newVariableWithInterfaceProperties
.
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken,
RequestHandlerDelegate<TResponse> next)
if (request is ICacheableQuery cachableRequest)
// here cachableRequest now has the interface properties.
【讨论】:
【参考方案3】:如果要在检查后使用类型转换的对象: 从 C# 7.0 开始:
if (obj is IMyInterface myObj)
这是一样的
IMyInterface myObj = obj as IMyInterface;
if (myObj != null)
请参阅 .NET 文档:Pattern matching overview
【讨论】:
【参考方案4】:我有一种情况,我将一个变量传递给一个方法,但不确定它是一个接口还是一个对象。
目标是:
-
如果 item 是一个接口,则基于该接口实例化一个对象,该接口是构造函数调用中的参数。
如果项目是对象,则返回 null,因为我的调用的构造函数需要一个接口,而我不希望代码陷入困境。
我通过以下方式实现了这一点:
if(!typeof(T).IsClass)
// If your constructor needs arguments...
object[] args = new object[] my_constructor_param ;
return (T)Activator.CreateInstance(typeof(T), args, null);
else
return default(T);
【讨论】:
【参考方案5】:@AndrewKennan 的答案的一个变体,我最近最终使用了在运行时获得的类型:
if (serviceType.IsInstanceOfType(service))
// 'service' does implement the 'serviceType' type
【讨论】:
【参考方案6】:这个Post 是一个很好的答案。
public interface IMyInterface
public class MyType : IMyInterface
这是一个简单的示例:
typeof(IMyInterface).IsAssignableFrom(typeof(MyType))
或
typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface))
【讨论】:
【参考方案7】:对我有用的是:
Assert.IsNotNull(typeof (YourClass).GetInterfaces().SingleOrDefault(i => i == typeof (ISomeInterface)));
【讨论】:
【参考方案8】:最近我尝试使用 Andrew Kennan 的答案,但由于某种原因它对我不起作用。我改用它并且它有效(注意:可能需要编写命名空间)。
if (typeof(someObject).GetInterface("MyNamespace.IMyInterface") != null)
【讨论】:
如果你最终走这条路,我不喜欢魔术字符串,所以我至少要把它改成 typeof(IMyInterface).Name 而不是“MyNamespace.IMyInterface”。有助于将重构证明命名为奖励。【参考方案9】:我用过
Assert.IsTrue(myObject is ImyInterface);
对于我的单元测试中的一个测试,它测试 myObject 是一个实现了我的接口 ImyInterface 的对象。
【讨论】:
【参考方案10】:如果您在编译时知道接口类型并且拥有您正在测试的类型的实例,则使用is
或as
运算符是正确的方法。似乎没有其他人提到过的是Type.IsAssignableFrom
:
if( typeof(IMyInterface).IsAssignableFrom(someOtherType) )
我认为这比查看GetInterfaces
返回的数组要简洁得多,并且还具有为类工作的优势。
【讨论】:
我试图确定一个类型是否实现了 IList 的一些实例化。我正在使用“typeof(IList).IsAssignableFrom(someType)”,但这不起作用。 您最好在另一个问题中提出这个问题。如果 someType 是列表元素的类型,您可能需要 typeof(IList).MakeGenericType(someType)。如果 someType 是列表类型,您应该查看 Type.GetGenericArguments 和 Type.GetGenericTypeDefinition。 我用它在插件系统中进行类型检查。它可用于对象实例尚不存在的情况。但我会同时使用这种风格和罗伯特的风格,这取决于我在做什么,所以我对这两种方式都投了赞成票。 这是一个较旧的评论,但要回答@Steenreem 的问题,请使用typeof(IList).IsAssignableFrom(someType)
,不要使用<>
。
此方法甚至适用于转换运算符,如果涉及 TypeConverters【参考方案11】:
除了使用“is”运算符进行测试之外,您还可以修饰方法以确保传递给它的变量实现特定接口,如下所示:
public static void BubbleSort<T>(ref IList<T> unsorted_list) where T : IComparable
//Some bubbly sorting
我不确定这是在哪个版本的 .Net 中实现的,因此它可能不适用于您的版本。
【讨论】:
这是 only compile-time 在这个线程中检查,谢谢。【参考方案12】:例如:
if (obj is IMyInterface)
对于班级:
检查typeof(MyClass).GetInterfaces()
是否包含接口。
【讨论】:
if (Array.IndexOf(typeof(MyClass).GetInterfaces(), typeof(IMyInterface)) != -1) ... 或者:if(typeof(MyClass).GetInterfaces().Contains(typeof(IMyInterface))) ...【参考方案13】:这应该可行:
MyInstace.GetType().GetInterfaces();
但也不错:
if (obj is IMyInterface)
甚至(不是很优雅):
if (obj.GetType() == typeof(IMyInterface))
【讨论】:
检查与 typeof(IMyInterface) 是否相等总是会失败。投反对票。 对。没有接口的实例。【参考方案14】:if (object is IBlah)
或
IBlah myTest = originalObject as IBlah
if (myTest != null)
【讨论】:
+1 第二个更好,因为您可能最终需要在第一个之后进行转换,从而给您两次转换(“is”,然后是显式转换)。使用第二种方法,您只需施放一次。 @Andrew:+1;又到了linkJulian M Bucknall 的经典 Double-Casting AntiPattern 博客文章的时间。 优化可能不会让你在第一种情况下投两次? @Joreen,如果您正在使用不能使用“as”的结构,则该链接会丢失一点,因为它不会包含“as”试图返回的空值,因为如果您必须通过像 int? 这样的可为空的类,但如果您只在接口级别工作则不是问题,因为它们始终是引用类型 C# 6.0 起:if (object is IBlah iblah) iblah.SomeMethod();
以上是关于测试对象是不是实现接口的主要内容,如果未能解决你的问题,请参考以下文章