我有两个班:

public class Question : IDisposable, IEquatable<Question>
{
}

public class SessionQuestion : Question, IDisposable, IEquatable<SessionQuestion>
{
}

Question继承IDisposableIEquatable时,SessionQuestion是否也隐式继承这些接口?

最佳答案

答案是“是”--接口是继承的。但是,是否可以省略包含类中的接口定义取决于该类是否希望将某些接口成员设置为explicit interface implementations
让我们举一个非常简单(愚蠢)的例子:

public interface IMyInterface
{
    void foo();
}

public class A : IMyInterface
{
    public void foo()
    {
        Console.Out.WriteLine("A.foo() executed");
    }
}

public class B : A, IMyInterface
{
    void IMyInterface.foo()
    {
        Console.Out.WriteLine("B.foo() executed");
    }
}

因为B希望foo()方法是explicit interface implementation,所以必须将imyinterface接口指定为其类定义的一部分——即使类A已经实现了这个接口。在这种情况下,从基类继承接口声明是不够的。
如果类B没有显式的接口实现,那么类B不需要再次指定接口(在这个小例子中是imyinterface)。
从基类继承一个接口并为该接口的成员提供一些显式接口实现,可能会产生一些效果,这些效果充其量是令人惊讶的,最坏的情况下可能会导致软件崩溃/出现错误。
如果执行以下代码序列:
A obj = new A();
obj.foo();
IMyInterface x = obj;
x.foo();

输出将是
a.foo()执行
a.foo()执行
但是,现在让我们使用B类型的对象,但在其他情况下保持代码完全相同:
B obj = new B();
obj.foo();
IMyInterface x = obj;
x.foo();

输出将有所不同:
a.foo()执行
b.foo()已执行
为什么会这样?请记住,类B继承了类A的foo()方法的实现。因此,调用obj.foo()仍将执行继承的foo()方法。
现在,为什么x.foo()不调用类a提供的foo()实现呢?或者,为什么obj.foo()不调用b类中foo()的实现?
因为x是imyinterface类型的变量,所以在调用x.foo()时,类型b的对象提供的foo()方法的显式接口实现优先。变量obj不是imyinterface类型,因此obj.foo()不会调用foo()方法的显式接口实现。
由于这些令人惊讶的结果,很容易理解为什么在大多数情况下,已经由基类实现的接口的显式接口实现实际上是一个坏主意。俗话说:不能因为你能,就意味着你应该。

09-16 04:24