判断一个类是否实现了接口,但不需要引用该接口

3
我认为这应该是完全可能的。我有一个接口,叫做“IJerry”。现在,我有一个类存在于变量“x”中。那个类完美地实现了“IJerry”接口。问题是,那个类从来没有引用过“IJerry”,它只是恰好具有与“IJerry”完全一致的签名而已。明白了吗?比如说,你创建了一个名为“MyClass”的类,它实现了“INotifyPropertyChanged”接口。然后你从该类中删除了“MyClass : INotifyPropertyChanged”声明,但保留了类内部的实现。是否有一种方法可以确定该类是否“实现”了一个接口,即使它没有明确引用它呢?

1
C#不支持鸭子类型:http://en.wikipedia.org/wiki/Duck_typing - Kirk Woll
2
@Kirk,请检查您链接中包含的信息。 - Anthony Pegram
@Anthony,哦,我明白了。文章提到使用动态关键字作为替代。在我看来,这不是“鸭子类型”,因为它没有提供通用操作的手段来处理满足该协议的类型的“类”。它只允许你“尝试”调用方法(如果存在的话)。 - Kirk Woll
我不能接受那些不是解决方案或答案的回答。但我明白你的观点,我会再次审查它们。 - Jerry Nixon
3个回答

7

不太容易。

您需要使用反射读取接口的字段、方法和属性,然后再使用反射检查类是否拥有它们。

或者,如果您正在使用C#4,您可以忘记IJerry,将MyClass放入动态变量中,让C#在运行时确定它所调用的方法。


糟糕,我本来还希望这是可能的。 - Jerry Nixon

2
实现接口比表面上看起来更为复杂。首先,即使您不使用virtual关键字,实现方法也是虚拟的。事实上,您不允许使用该关键字。其次,编译器会重新排列方法以匹配接口的方法表布局。从声明中删除继承的接口将“保证”结果不兼容。方法将不再是虚拟的。
你追求的是所谓的“动态分派”。它在DLR中实现,并集成到.NET 4.0和C# 4.0语言中。重新发明System.Reflection代码并使其高效是一项重大任务。

1

你需要使用反射来查看x是否有与IJerry上的方法匹配的方法。真正的问题是,你打算用这个答案做什么?在版本4之前,C#不支持“鸭子类型”,因此为了在需要IJerry的地方使用你的类,你必须编写适配器代码。


C# 4 可以进行动态类型编程。反射方法也可以被调用。 - Anthony Pegram

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接