我正在学习来自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())。
我想解决方案很简单,但我尝试了各种各样的事情,因为我的生活无法解决这个问题。
答案 0 :(得分:42)
您遇到了问题,因为您使用了 explicit interface implementation (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:
答案 1 :(得分:8)
将您的声明更改为:
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool()
{
Console.Write("I did something cool.");
}
}
答案 2 :(得分:7)
实现接口的方式是显式实现void IDoesCoolThings.DoCool(),如果选择隐式实现接口。
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool()
{
Console.Write("I did something cool.");
}
}
然后它会起作用。
阅读本文:
C# Interfaces. Implicit implementation versus Explicit implementation
答案 3 :(得分:1)
你应该这样做:
public interface IDoesCoolThings
{
void DoCool();
}
public abstract class AbstractWidget
{
public void DoCool()
{
Console.WriteLine("I did something cool.");
}
}
public class Widget : AbstractWidget, IDoesCoolThings
{
}
用法:
var widget = new Widget();
widget.DoCool();