简体   繁体   English

C#和接口 - 显式与隐式

[英]C# and Interfaces - Explicit vs. Implicit

In C#, if a class has all the correct methods/signatures for an Interface , but doesn't explicitly implement it like: 在C#中,如果一个类具有接口的所有正确方法/签名 ,但没有明确地实现它,如:

class foo : IDoo {}

Can the class still be cast as that interface? 该类仍然可以作为该接口进行转换吗?

Duck Typing 鸭子打字

What you are alluding to is referred to as " duck-typing " (named after the idiom "if it looks like a duck, and quacks like a duck, then it must be a duck"). 你所暗示的被称为“ 鸭子打字 ”(以成语命名“如果它看起来像一只鸭子,像鸭子那样嘎嘎叫,那么它一定是鸭子”)。

With duck-typing an interface implementation is implicit once you have implemented the relevant members (just as you describe) however .NET does not currently have any broad support for this. 使用duck-typing,一旦你实现了相关的成员(就像你描述的那样),接口实现是隐式的,但是.NET目前没有对此有任何广泛的支持。

With the emergent dynamic language features planned for the future, I wouldn't be surprised if this were supported natively by the runtime in the near future. 通过为未来规划的紧急动态语言功能,如果在不久的将来运行时支持本机,我不会感到惊讶。

In the mean time, you can synthesise duck-typing via reflection, with a library such as this , which would allow you to do a duck-typed cast like this: IDoo myDoo = DuckTyping.Cast<IDoo>(myFoo) 同时,您可以通过反射合成鸭子类型,使用这样的库 ,这将允许您执行这样的鸭子类型转换: IDoo myDoo = DuckTyping.Cast<IDoo>(myFoo)

Some Trivia 一些琐事

Interestingly, there is one small place where duck-typing is in use in C# today — the foreach operator. 有趣的是,今天在C#中有一个小型的地方正在使用鸭子打字 - foreach操作员。 Krzysztof Cwalina states that in order to be enumerable by the foreach operator, a class must: Krzysztof Cwalina 指出 ,为了被foreach运算符枚举,一个类必须:

Provide a public method GetEnumerator that takes no parameters and returns a type that has two members: a) a method MoveMext that takes no parameters and return a Boolean, and b) a property Current with a getter that returns an Object. 提供一个不带参数的公共方法GetEnumerator,并返回一个包含两个成员的类型:a)一个方法MoveMext,它不带参数并返回一个布尔值,和b)一个属性Current,带有一个返回Object的getter。

Notice that he makes no mention of IEnumerable nor IEnumerator . 请注意,他没有提到IEnumerableIEnumerator Although it is common to implement these interfaces when creating an enumerable class, if you were to drop the interfaces but leave the implementation, your class would still be enumerable by foreach . 虽然在创建可枚举类时实现这些接口是很常见的,但是如果您要删除接口但是保留实现,那么您的类仍然可以通过foreach枚举。 Voila! 瞧! Duck-typing! 鸭打字! ( Example code here .) 这里的示例代码 。)

No, it's not like Objective-C and some other languages. 不,它不像Objective-C和其他一些语言。 You should explicitly declare interface implementation. 您应该显式声明接口实现。

Provided that IDoo has any members, this code won't compile. 如果IDoo有任何成员,则此代码将无法编译。 If IDoo has no members, then yes, the cast is safe (but obviously of limited use). 如果IDoo没有成员,那么是的,演员是安全的(但显然是有限的使用)。

This would basically require Duck Typing to work in C#, which does not happen automatically. 这基本上要求Duck Typing在C#中工作,这不会自动发生。

There are some libraries that can do this, though. 但是,有些可以做到这一点。

public class A
{
   public void DoSomething();
}

public interface IDoSomething
{
   void DoSomething();
}

public class B : A, IDoSomething
{ }

B satisfies IDoSomething.DoSomething by inheriting from A B通过继承A来满足IDoSomething.DoSomething

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM