我正在学习来自C++的C#并且遇到了问题.
我有一个抽象类AbstractWidget,一个接口IDoesCoolThings,以及一个派生自AbstractWidget的类,名为RealWidget:
public interface IDoesCoolThings { void DoCool(); } public abstract class AbstractWidget : IDoesCoolThings { void IDoesCoolThings.DoCool() { Console.Write("I did something cool."); } } public class RealWidget : AbstractWidget { }
当我实例化一个RealWidget对象并在其上调用DoCool()时,编译器给出了一个错误说法
'RealWidget'不包含'DoCool'的定义
我可以将RealWidget对象转换为IDoesCoolThings,然后调用就可以了,但这似乎是不必要的,我也失去了多态性(即使我定义了RealWidget.DoCool(),也总是会调用AbstractWidget.DoCool()).
我想解决方案很简单,但我尝试了各种各样的事情,因为我的生活无法想象这一点.
您遇到了问题,因为您使用了显式接口实现(EII).当显式实现成员时,不能通过类实例访问它 - 只能通过接口的实例访问它.在您的示例中,这就是DoCool()
除非您将实例强制转换为无法调用的原因IDoesCoolThings
.
解决方案是DoCool()
公开并删除显式接口实现:
public abstract class AbstractWidget : IDoesCoolThings { public void DoCool() // DoCool() is part of the abstract class implementation. { Console.Write("I did something cool."); } } // ... var rw = new RealWidget(); rw.DoCool(); // Works!
通常,您在两种情况下使用EII:
您有一个必须实现两个接口的类,每个接口都包含一个与另一个接口中另一个成员具有相同名称/签名的成员.
您希望强制客户端不依赖于您的类的实现细节,而是依赖于您的类实现的接口.(这被一些人认为是一种很好的做法.)
将您的声明更改为:
public abstract class AbstractWidget : IDoesCoolThings { public void DoCool() { Console.Write("I did something cool."); } }
实现接口的方式是显式实现void IDoesCoolThings.DoCool(),如果选择隐式实现接口.
public abstract class AbstractWidget : IDoesCoolThings { public void DoCool() { Console.Write("I did something cool."); } }
然后它会工作.
读这个 :
C#接口.隐式实现与显式实现