测试对象是否实现接口


Answers:


569
if (object is IBlah)

要么

IBlah myTest = originalObject as IBlah

if (myTest != null)

85
+1第二个更好,因为您可能最终需要在第一个之后进行强制转换,从而给您两个强制转换(“ is”然后是显式强制转换)。使用第二种方法,您只需要投放一次。
安德鲁·黑尔

51
@安德鲁:+1; 再次链接Julian M Bucknall撰写的经典Double-Casting AntiPattern博客文章。
Jeroen Wiert Pluimers 2011年

1
优化可能不会让您在第一种情况下投放两次?
BuZz 2013年

1
@Joreen,如果您使用的结构不能使用“ as”,则该链接会遗漏一点,因为它不会包含null,而这正是“ as”试图返回的内容,在这种情况下,您必须经过可为null的对象类如int?虽然不是如果问题只是你在接口级合作,因为他们总是引用类型
MikeT

46
自C#6.0起:if (object is IBlah iblah) { iblah.SomeMethod(); }
Knelis

224

如果您在编译时知道接口类型并具有要测试的类型的实例,则使用isor as运算符是正确的方法。似乎没有人提到的一件事是Type.IsAssignableFrom

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

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


我试图确定一种类型是否实现了IList的某些实例。我正在使用“ typeof(IList <>)。IsAssignableFrom(someType)”,但是这不起作用。
KeyboardDrummer

3
您最好在另一个问题中提出这个问题。如果someType是列表元素的类型,则可能需要typeof(IList <>)。MakeGenericType(someType)。如果someType是列表类型,则应查看Type.GetGenericArguments和Type.GetGenericTypeDefinition。
安德鲁·肯南

我用它来检查插件系统中的类型。它可以在对象实例尚不存在的情况下使用。但是我会根据自己的风格同时使用这种风格和Robert的风格,因此我对两种方式都投了赞成票。
詹姆斯

这是较旧的评论,但要回答@Steenreem的问题,请使用typeof(IList).IsAssignableFrom(someType),而不使用<>
saluce

此方法甚至适用于转换运算符,并且如果涉及TypeConverters,则该方法
Harald Coppoolse 2014年

22

对于实例:

if (obj is IMyInterface) {}

对于班级:

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


1
if(Array.IndexOf(typeof(MyClass).GetInterfaces(),typeof(IMyInterface))!= -1){...}
Constantin

2
或:if(typeof(MyClass).GetInterfaces()。Contains(typeof(IMyInterface))){...}
Lance Fisher


16

@AndrewKennan的答案的一个变体我最近在运行时获得了用于类型的结果:

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

7

这个帖子是一个很好的答案。

public interface IMyInterface {}

public class MyType : IMyInterface {}

这是一个简单的示例:

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

要么

typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface))

3

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

public static void BubbleSort<T>(ref IList<T> unsorted_list) where T : IComparable
{
     //Some bubbly sorting
}

我不确定在哪个版本的.Net中实现,因此它可能不适用于您的版本。


2
.net 2.0添加了泛型。
罗伯特·巴特

这是唯一的 编译时间在此线程检查,谢谢。
达斯汀·马龙

2

对我有用的是:

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


1

最近,我尝试使用安德鲁·肯南(Andrew Kennan)的答案,由于某种原因,它对我不起作用。我改用了它,它起作用了(注意:可能需要编写名称空间)。

if (typeof(someObject).GetInterface("MyNamespace.IMyInterface") != null)

2
如果您最终选择这条路线,则我不喜欢魔术弦,因此我至少要将其更改为typeof(IMyInterface).Name而不是“ MyNamespace.IMyInterface”。有助于使其成为名称重构证明的奖励。
greyalien007

0

我用了

Assert.IsTrue(myObject is ImyInterface);

用于我的单元测试中的测试,该测试测试myObject是实现了我的接口ImyInterface的对象。


-1

我遇到了将变量传递给方法的情况,但不确定是接口还是对象。

目标是:

  1. 如果item是接口,则基于该接口实例化一个对象,该接口是构造函数调用中的参数。
  2. 如果该项目是一个对象,则返回空值,因为用于我的调用的构造函数需要一个接口,并且我不希望代码被加载。

我做到了以下几点:

    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);

-12

这应该工作:

MyInstace.GetType().GetInterfaces();

但也很好:

if (obj is IMyInterface)

甚至(不是很优雅):

if (obj.GetType() == typeof(IMyInterface))

9
检查与typeof(IMyInterface)是否相等将始终失败。不赞成投票。
杰伊·巴祖兹

对。没有接口的实例。
Rauhotz
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.