在 C# 中,如果一个类具有接口的所有正确方法/签名,但没有像这样显式实现它:
class foo : IDoo {}
该类仍然可以转换为该接口吗?
在 C# 中,如果一个类具有接口的所有正确方法/签名,但没有像这样显式实现它:
class foo : IDoo {}
该类仍然可以转换为该接口吗?
鸭打字
您所指的是“鸭式打字”(以“如果它看起来像鸭子,并且像鸭子一样嘎嘎,那么它一定是鸭子”的成语命名)。
使用鸭子类型,一旦您实现了相关成员(正如您所描述的那样),接口实现就是隐式的,但是.NET 目前对此没有任何广泛的支持。
有了为未来计划的新兴动态语言功能,如果在不久的将来运行时本机支持它,我不会感到惊讶。
同时,您可以通过反射合成鸭子类型,使用这样的库,这将允许您执行如下所示的鸭子类型转换:IDoo myDoo = DuckTyping.Cast<IDoo>(myFoo)
一些琐事
有趣的是,今天在 C# 中使用鸭子类型的一个小地方 -foreach
运算符。Krzysztof Cwalina指出,为了被foreach
运算符枚举,一个类必须:
提供一个不带参数并返回具有两个成员的类型的公共方法 GetEnumerator:a) 不带参数并返回 Boolean 的方法 MoveMext,以及 b) 具有返回 Object 的 getter 的属性 Current。
请注意,他没有提到IEnumerable
nor IEnumerator
。尽管在创建可枚举类时实现这些接口很常见,但如果您要删除接口但离开实现,您的类仍然可以通过foreach
. 瞧!鸭打字!(示例代码在这里。)
不,它不像 Objective-C 和其他一些语言。您应该显式声明接口实现。
如果 IDoo 有任何成员,则此代码将无法编译。如果 IDoo 没有成员,那么是的,演员表是安全的(但显然用途有限)。
这基本上需要 Duck Typing 在 C# 中工作,这不会自动发生。
不过,有一些库可以做到这一点。
public class A
{
public void DoSomething();
}
public interface IDoSomething
{
void DoSomething();
}
public class B : A, IDoSomething
{ }
B 通过从 A 继承满足 IDoSomething.DoSomething