c# – 在没有警告的情况下隐藏基类的显式接口实现的目的?

想象一下这些规范来自外部dll.一个显式实现接口的类:

public interface IDebug
{
    string GetImportantInfo();
}
public class ExternalClass : IDebug
{
    public void DoSomethingImportant()
    {
        System.Diagnostics.Debug.WriteLine("Something important was done...");
    }
    string IDebug.GetImportantInfo() //Explicit implementation
    {
        DoSomethingImportant();
        return nameof(ExternalClass);
    }
}

然后这个来自内部代码,您知道需要实现该接口:

public class Debug : ExternalClass, IDebug
{
    public string GetImportantInfo()
    {
        return nameof(Debug);
    }
}

现在,当我从子类调用Debug的GetImportantInfo()方法时,不会调用超类中的显式实现:

static void Main(string[] args)
{
    IDebug test = new Debug();
    var impInfo = test.GetImportantInfo();
    System.Diagnostics.Debug.WriteLine(impInfo); //"Debug"
}

我似乎得到的唯一一个小提示是,在将IDebug接口添加到Debugclass时,我没有遇到编译错误,而没有实现该方法:

public class Debug : ExternalClass, IDebug
{
}

当你覆盖这样的超类的实现时,为什么没有编译警告?如果基类隐式实现它,我会收到一个编译警告,告诉我使用new关键字.但是使用new关键字覆盖显式实现的方法会产生编译警告:

The member ‘Program.Debug.GetImportantInfo()’ does not hide an inherited member. The new keyword is not required.

是否有预期目的,或者这是一个错误?如果有意,官方推理是什么?

最佳答案 这里的问题是你使用的语言鲜为人知:界面重新实现:

public class Debug : ExternalClass, IDebug
{
    public string GetImportantInfo()
    {
        return nameof(Debug);
    }
}

如果ExternalClass已经执行,为什么要重新声明Debug实现IDebug?你正在重新实现界面,因为你正在做这样的事情,你没有得到任何警告;编译器假定您知道自己在做什么.

如果您想要您想要的行为,只需不要重新实现该接口:

public class Debug : ExternalClass
{
    public string GetImportantInfo()
    {
        return nameof(Debug);
    }
}

If the base class implements it implicitly, I get a compile warning telling me to use the new keyword.

此警告与接口实现无关.警告只是由于方法隐藏,你有两个方法具有相同的签名; IDebug在这里是一个非因素,你可以把它排除在等式之外,你仍然会得到同样的警告.

In my colleague’s case, he said he had to implement both the base class and the interface because it was an event-based interface.

好吧,然后告诉你的同事找出他想要的东西.如果重新实现接口,那么对DoSomething的任何调用,无论是通过Debug类型引用还是IDebug类型引用,都应该调用重新实现的行为.任何其他行为都会出乎意料而且令人深感困惑.

另一方面,如果您需要保持基类的原始行为,如果通过IDebug类型引用调用DoSomething(),则不要重新实现该接口.您还有其他选择吗?

这是否意味着您应该知道基类实现的接口?嗯,是的,当然.我发现你的问题是为什么任何人都应该知道你要从实现中继承的任何给定类的接口,实在是非常令人担忧.

点赞