为什么C#中的基类允许实现接口契约而不继承它?

时间:2010-05-31 10:00:22

标签: c# interface base-class

我偶然发现了C#的这个“功能” - 实现接口方法的基类不必从中派生

示例:

public interface IContract
{
    void Func();
}

// Note that Base does **not** derive from IContract
public abstract class Base
{
    public void Func()
    {
        Console.WriteLine("Base.Func");
    }
}

// Note that Derived does *not* provide implementation for IContract
public class Derived : Base, IContract
{
}

Derived会神奇地采用公共方法Base.Func,并决定它将实施IContract.Func

这种魔法背后的原因是什么?

恕我直言:这种“准实现”功能非常不直观,使代码检查更加困难。你觉得怎么样?

2 个答案:

答案 0 :(得分:32)

原因是您的评论完全不正确:

  

//请注意,Derived 为IContract

提供实现

确实如此。遵循逻辑。

  • 派生需要提供与IContract的每个成员相对应的公共成员。
  • 基类的所有可继承成员也是派生类的成员;这是继承的定义
  • 因此Derived为IContract提供了一个实现;其继承的成员是满足要求的成员
  • 因此,没有错误。
  

此功能非常不直观,使代码检查更加困难。你觉得怎么样?

我认为如果你不喜欢它,你不应该使用这个功能。如果您发现使用此功能的代码令人困惑和奇怪,那么请鼓励使用此功能的同事停止这样做。

此功能与派生类中使用基类的方法的任何其他功能有何不同?在派生类中可以使用或提及基类中的方法有多种不同的方法 - 方法调用,覆盖,方法组转换等。

此外,相对而言,这是一个简单明了的案例。如果你真的想抱怨在C#中混淆界面语义,我会花时间抱怨接口重新实现语义。那个真的好像烤人的面条。我总是要在规范中查看这一点,以确保我的语义正确。

答案 1 :(得分:12)

为什么你认为这很奇怪而且不自然?基类的每个公共成员也是派生类的公共成员。所以这里没有矛盾。无论如何,如果你愿意,你可以明确地实现界面。