10

在 C# 中,如果一个类具有接口的所有正确方法/签名,但没有像这样显式实现它:

class foo : IDoo {}

该类仍然可以转换为该接口吗?

4

5 回答 5

17

鸭打字

您所指的是“鸭式打字”(以“如果它看起来像鸭子,并且像鸭子一样嘎嘎,那么它一定是鸭子”的成语命名)。

使用鸭子类型,一旦您实现了相关成员(正如您所描述的那样),接口实现就是隐式的,但是.NET 目前对此没有任何广泛的支持。

有了为未来计划的新兴动态语言功能,如果在不久的将来运行时本机支持它,我不会感到惊讶。

同时,您可以通过反射合成鸭子类型,使用这样的库,这将允许您执行如下所示的鸭子类型转换:IDoo myDoo = DuckTyping.Cast<IDoo>(myFoo)

一些琐事

有趣的是,今天在 C# 中使用鸭子类型的一个小地方 -foreach运算符。Krzysztof Cwalina指出,为了被foreach运算符枚举,一个类必须:

提供一个不带参数并返回具有两个成员的类型的公共方法 GetEnumerator:a) 不带参数并返回 Boolean 的方法 MoveMext,以及 b) 具有返回 Object 的 getter 的属性 Current。

请注意,他没有提到IEnumerablenor IEnumerator。尽管在创建可枚举类时实现这些接口很常见,但如果您要删除接口但离开实现,您的类仍然可以通过foreach. 瞧!鸭打字!(示例代码在这里。)

于 2009-04-24T21:11:49.210 回答
12

不,它不像 Objective-C 和其他一些语言。您应该显式声明接口实现。

于 2009-04-24T20:48:48.873 回答
4

如果 IDoo 有任何成员,则此代码将无法编译。如果 IDoo 没有成员,那么是的,演员表是安全的(但显然用途有限)。

于 2009-04-24T20:50:48.107 回答
3

这基本上需要 Duck Typing 在 C# 中工作,这不会自动发生。

不过,有一些可以做到这一点。

于 2009-04-24T21:06:38.833 回答
2
public class A
{
   public void DoSomething();
}

public interface IDoSomething
{
   void DoSomething();
}

public class B : A, IDoSomething
{ }

B 通过从 A 继承满足 IDoSomething.DoSomething

于 2009-04-24T20:54:58.050 回答