测试对象是不是实现接口

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 =&gt; 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】:

如果您在编译时知道接口类型并且拥有您正在测试的类型的实例,则使用isas 运算符是正确的方法。似乎没有其他人提到过的是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),不要使用&lt;&gt; 此方法甚至适用于转换运算符,如果涉及 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();

以上是关于测试对象是不是实现接口的主要内容,如果未能解决你的问题,请参考以下文章

C#:使用实现私有接口的对象参数测试方法

如何测试一个类是不是实现了另一个类的所有接口?

接口测试该怎么做

深度解读接口测试...

10年测试专家深度解读接口测试

接口测试中注意的问题