C# 测试对象是否实现了接口

C# 测试对象是否实现了接口,c#,reflection,interface,C#,Reflection,Interface,如果一个对象在C#中实现了一个给定的接口,最简单的测试方法是什么?(对这一问题的答复 ) 或 例如: if (obj is IMyInterface) {} 对于班级: 检查typeof(MyClass).GetInterfaces()是否包含该接口。这应该可以: MyInstace.GetType().GetInterfaces(); 但也很好: if (obj is IMyInterface) 甚至(不是很优雅): 除了使用“is”操作符进行测试外,您还可以修饰您的方法,以确保传递给它

如果一个对象在C#中实现了一个给定的接口,最简单的测试方法是什么?(对这一问题的答复 )

例如:

if (obj is IMyInterface) {}
对于班级:

检查
typeof(MyClass).GetInterfaces()是否包含该接口。

这应该可以:

MyInstace.GetType().GetInterfaces();
但也很好:

if (obj is IMyInterface)
甚至(不是很优雅):


除了使用“is”操作符进行测试外,您还可以修饰您的方法,以确保传递给它的变量实现特定接口,如下所示:

public static void BubbleSort<T>(ref IList<T> unsorted_list) where T : IComparable
{
     //Some bubbly sorting
}
publicstaticvoidbubblesort(参考IListunsorted_列表),其中T:IComparable
{
//一些冒泡的分类
}

我不确定这是在哪个版本的.Net中实现的,因此它可能无法在您的版本中工作。

如果您在编译时知道接口类型,并且有您正在测试的类型的实例,则使用
is
as
运算符是正确的方法。其他人似乎没有提到的东西是
类型。IsAssignableFrom

if( typeof(IMyInterface).IsAssignableFrom(someOtherType) )
{
}

我认为这比查看由
GetInterfaces
返回的数组要简洁得多,而且还具有为类工作的优点。

最近我使用@AndrewKennan的答案的一个变体来处理运行时获得的类型:

if (serviceType.IsInstanceOfType(service))
{
    // 'service' does implement the 'serviceType' type
}
我曾经

Assert.IsTrue(myObject是ImyInterface)


在我的单元测试中,测试myObject是否是一个实现了接口ImyInterface的对象。

最近,我尝试使用Andrew Kennan的答案,但由于某种原因,它对我无效。我改为使用了这个名称空间,它起了作用(注意:可能需要编写名称空间)

对我起作用的是:

Assert.IsNotNull(typeof(YourClass).GetInterfaces().SingleOrDefault(i=>i==typeof(ISomeInterface))

这是一个很好的答案

public interface IMyInterface {}

public class MyType : IMyInterface {}
这是一个简单的示例:

typeof(IMyInterface).IsAssignableFrom(typeof(MyType))


如果要在检查后使用typecasted对象:
自C#7.0以来:

这和

IMyInterface myObj = obj as IMyInterface;
if (myObj != null)

请参阅.NET文档:

我遇到过这样一种情况:我将一个变量传递给一个方法,不确定它是一个接口还是一个对象

目标是:

  • 如果项是接口,则基于该接口实例化对象,该接口是构造函数调用中的参数
  • 如果该项是一个对象,则返回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);
    

    检查是否与typeof(IMyInterface)相等总是会失败。否决票,对。没有接口的实例。if(Array.IndexOf(typeof(MyClass).GetInterfaces(),typeof(IMyInterface))!=-1{…}或:if(typeof(MyClass).GetInterfaces().Contains(typeof(IMyInterface)){…}+1第二个更好,因为之后可能需要对第一个进行强制转换,从而提供两个强制转换(“is”然后进行显式转换)。第二种方法只能施放一次。@Andrew:+1;又到了经典的双模式反模式博客帖子的时间了。优化可能不会让你在第一种情况下施放两次?@Joreen,如果你使用的是一个不能使用“as”的结构,那么这个链接会漏掉一点,因为它不会保留一个空值,而“as”试图返回这个空值,在这种情况下,您必须经历一个像int?这样的可为null的类,但如果您只在接口级别工作,因为它们总是引用typesSince C#6.0:
    if(object is IBlah IBlah){IBlah.SomeMethod();}
    我试图确定某个类型是否实现了IList的某些实例化,这不是问题。我正在使用“typeof(IList).IsAssignableFrom(someType)”,但这不起作用。你最好在另一个问题中问这个问题。如果someType是列表元素的类型,则可能需要typeof(IList)。MakeGenericType(someType)。如果someType是列表类型,您应该查看type.GetGenericArguments和type.GetGenericTypeDefinition。我使用它在插件系统中进行类型检查。它可用于对象实例尚不存在的情况。但我同时使用这种风格和Robert的风格,这取决于我正在做什么,所以我对两种方式都投了赞成票。这是一个较旧的评论,但要回答@Steenreem的问题,请使用
    typeof(IList)。IsAssignableFrom(someType)
    ,没有
    。此方法甚至可以与转换运算符一起使用,如果您最终使用了类型转换器,我不喜欢神奇字符串,因此我至少会将其更改为typeof(IMyInterface).Name而不是“MyNamespace.IMyInterface”。有助于将其命名为重构证明作为奖励。这是此线程中唯一的编译时检查,谢谢。
    public interface IMyInterface {}
    
    public class MyType : IMyInterface {}
    
    typeof(IMyInterface).IsAssignableFrom(typeof(MyType))
    
    typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface))
    
    if (obj is IMyInterface myObj)
    
    IMyInterface myObj = obj as IMyInterface;
    if (myObj != 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);