C#可以标记并检查类何时实现接口方法?

时间:2014-10-08 13:10:28

标签: c# interface override

当基类包含virtual方法时,要在子类中添加更多派生版本,我们必须使用override

AFAICT,这有两个目的:

  • 我们不会意外地覆盖基本方法
  • 如果我们想要覆盖时输错方法名称,我们会收到错误(similar to Java,对吧?)

然而,让我感到沮丧的是(在VS2010 / .NET4中)实现接口方法时 无法使用override

显然,第一个项目符号不是问题,但override关键字可以作为一个很好的简单文档,并检查接口方法实际上是否标记为override

因此,在查看类实现时,是否有任何方式其他而不是// comment来指示此方法实现某个接口的方法?

3 个答案:

答案 0 :(得分:1)

  

然而,让我感到沮丧的是(在VS2010 / .NET4中),在实现接口方法时不可能使用覆盖。

那是因为界面方法没有被覆盖,所以它们已经被实现了。这是一个看似微不足道的语义差异,但是当我们谈论语言语义的使用时非常重要。

  

但覆盖关键字可以作为一个很好的简单文档,并检查接口方法实际上是否被标记为覆盖

这不会有点误导吗? override意味着基类定义被覆盖了。 The MSDN documentation将其定义为:

  

需要使用override修饰符来扩展或修改继承的方法,属性,索引器或事件的抽象或虚拟实现。

接口不会被继承,它们会被实施。再次,只是语义,但一个非常重要的区别。一个类可以实现多个接口,相同的方法可以应用于多个接口定义等。

覆盖继承的行为意味着:

  • 存在继承行为(在virtual的情况下使用默认实现,或者在abstract的情况下使用默认实现),请记住C#是单继承语言
  • 正在重写实现(当父类在内部调用该成员时,它在继承模型中具有特定的区别)

这些条件不适用于接口。

  

那么,在查看类实现时,除了//注释之外还有什么方法可以表明此方法实现了某个接口的方法吗?

实际上,是的。你可以explicitly implement an interface。像这样:

interface IDimensions 
{
   float Length();
   float Width();
}

class Box : IDimensions
{
    public float IDimensions.Length() 
    {
        // implementation
    }

    public float IDimensions.Width() 
    {
        // implementation
    }
}

答案 1 :(得分:0)

假设您有以下类型:

interface ISampleInterface
{
    void Method();
}

class A : ISampleInterface
{
    public void Method()
    {
    }
}

class B : A, ISampleInterface
{
    void ISampleInterface.Method()
    {
    }
}

class C : A, ISampleInterface
{
    public new void Method()
    {
    }
}

并以这种方式使用它们:

ISampleInterface a = new A();
ISampleInterface b = new B();
ISampleInterface c = new C();

a.Method(); // calls A.Method
b.Method(); // calls explicit ISampleInterface.Method
((B)b).Method(); // calls A.Method
c.Method(); // calls C.Method
((A)c).Method(); // calls A.Method

看起来很难定义,Method的哪些实现可以标记为override

答案 2 :(得分:0)

我相信关于你关注的一切都用这句话来概括:

  

但覆盖关键字可以很简单   记录并检查接口方法实际上是这些   被标记为覆盖。

考虑什么是界面,以及实施者是什么。类可以实现也可以不实现接口,并且仍然可以实现具有与接口相同的签名的方法。 界面的作用是确保某些班级有必要的成员来完成合同。

例如,课程Calculator可以实施ICalculatorCalculator实施Addition(int, int)。但Calculator无法实现ICalculator,无论如何都可以执行Addition(int, int)

你如何区分这两种情况?何时使用override或不使用Calculator

另一点:很高兴实现一个类,并实现一个接口,并通过在继承冒号之后将其从类签名中删除来停止实现它。

另一方面,认为您正在寻找的文档是编译器错误,告诉您ICalculator实现了接口ICalculator,但它没有&#39 ; t声明并实现Calculator定义的一个或多个成员。如果代码编译,您不应该关心成员是否属于某个或其他界面。您知道某些成员是某些界面的实现,因为您的public class Calculator : ICalculator签名如下所示:override

此外,实现成员实现它以实现多于接口的情况。什么超越了您的实施?这不是比避免{{1}}关键字更令人困惑吗?