C# 如何使用虚拟方法显式实现接口?

C# 如何使用虚拟方法显式实现接口?,c#,.net,inheritance,interface,virtual-functions,C#,.net,Inheritance,Interface,Virtual Functions,我不能这么做 interface InterfaceA { void MethodA(); } class ClassA : InterfaceA { virtual void InterfaceA.MethodA() // Error: The modifier 'virtual' is not valid for this item { } } 以下工作在哪里 class ClassA : InterfaceA { public virtu

我不能这么做

interface InterfaceA
{
    void MethodA();
}

class ClassA : InterfaceA
{
    virtual void InterfaceA.MethodA()
    // Error: The modifier 'virtual' is not valid for this item
    {
    }
}
以下工作在哪里

class ClassA : InterfaceA
{
    public virtual void MethodA()
    {
    }
}

为什么??如何避免这种情况?

您不能将虚拟修饰符与静态、抽象、私有或覆盖修饰符一起使用。 默认修饰符是私有的

它是C语言规范的一部分:


我认为这是因为当一个成员显式实现时,它不能通过类实例访问,而只能通过接口的实例访问。

因此,在这种情况下,将某些内容设置为“虚拟”是没有意义的,因为虚拟意味着您打算在继承的类中重写它。显式实现接口和虚拟化接口是矛盾的。这也可能是编译器不允许这样做的原因

为了解决这个问题,我认为或回答听起来像是根据C#language spec(语言规范)

这是一个编译时错误 显式接口成员 实施包括访问 修饰符,这是一个编译时 包含修改器时出错 抽象、虚拟、重写或 静态的


您只能通过从显式接口实现调用虚拟方法来“绕过”它。

您必须执行以下操作:

interface InterfaceA
{
    void MethodA();
}

class ClassA : InterfaceA
{
    void InterfaceA.MethodA()
    { MethodB(); }

    protected virtual void MethodB()
    { 
    }
}
通常这是一种优越的方法,因为内部方法可能会在不更改接口的情况下更改签名。以一个更真实的单词为例:

interface IOrderDetails
{
    void PlaceOrder();
}

//Sometime later you extend with:
interface IOrderDetails2 : IOrderDetails
{
    void PlaceOrder(IUser user);
}

//Implementation
class Order : IOrderDetails, IOrderDetails2
{
    static readonly IUser AnonUser;

    void IOrderDetails.PlaceOrder()
    { OnPlaceOrder(AnonUser); }
    void IOrderDetails2.PlaceOrder(IUser user)
    { OnPlaceOrder(user); }

    protected virtual void OnPlaceOrder(IUser user)
    { 
    }
}

在这里您可以看到,随着IOrderDetails2的添加,我们可以安全地重构现有的虚拟方法(从而为派生生成编译时错误)。此外,这通常允许您在基本实现类中提供公共功能、日志记录和异常处理…

有趣的是,对于显式实现,修饰符是公共的,尽管只有当实例转换为相应的接口类型时才能访问修饰符。为什么要绕过它?这又有什么好处呢?@Eric这会帮我省下一些打字的时间。为什么不允许将显式接口方法标记为虚拟方法会导致你更多地打字?这是一个很好的解释,解释了为什么想要这样做没有意义。