C#能在类实现接口方法时进行标记和检查吗?

C#能在类实现接口方法时进行标记和检查吗?,c#,interface,overriding,C#,Interface,Overriding,当基类包含virtual方法时,要在子类中添加更派生的版本,我们必须使用override AFAICT有两个目的: 我们不会意外地跳过基本方法 如果我们在想要重写时输入错误的方法名,我们会得到一个错误(,对吗?) 然而,令我失望的是,(在VS2010/.NET4中)在实现接口方法时,似乎不可能使用覆盖 显然,第一个项目符号不是问题,但是override关键字可以作为一个很好的简单文档,并检查接口方法是否实际上是标记为override的方法 因此,在查看类实现时,除了注释之外,是否有其他方法指

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

AFAICT有两个目的:

  • 我们不会意外地跳过基本方法
  • 如果我们在想要重写时输入错误的方法名,我们会得到一个错误(,对吗?)
然而,令我失望的是,(在VS2010/.NET4中)在实现接口方法时,似乎不可能使用
覆盖

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


因此,在查看类实现时,除了注释之外,是否有其他方法指示此方法实现了某个接口的方法?

假设您有以下类型:

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

看起来很难定义,
方法
的哪种实现可以标记为
覆盖

,我相信这句话概括了您所关心的一切:

但是这个超控键可以作为一个很好的简单 记录并检查接口方法是否与这些方法相同 标记为覆盖的

想想什么是接口,什么是实现者。类可以实现接口,也可以不实现接口,并且仍然可以实现具有与接口相同签名的方法。接口所做的工作是确保某些类具有完成契约所需的成员

例如,类
计算器
可以实现
ICalculator
计算器
实现
加法(int,int)
。但是
Calculator
无法实现
ICalculator
,它可以执行
加法(int,int)

你如何区分这两种情况?何时使用
覆盖

另一点:最好实现一个类,实现一个接口,然后通过在继承冒号之后从类签名中删除它来停止实现它

另一方面,假设您正在查找的文档是编译器错误,它告诉您,
Calculator
实现接口
ICalculator
,但它没有声明和实现由
ICalculator
定义的一个或多个成员。如果代码已编译,则不应关心成员是否属于某个或其他接口。您知道有些成员是某些接口的实现,因为您的
计算器
签名如下:
公共类计算器:ICalculator

此外,在这种情况下,实现成员实现它不仅仅是为了实现一个接口。什么在覆盖您的实现?这不是比避免使用
覆盖
关键字更令人困惑吗

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

这是因为接口方法不是被重写的,而是被实现的。这是一个看似微不足道的语义差异,但当我们谈论语言的使用时,语义是非常重要的

但是overridekeyword可以作为一个很好的简单文档,并检查接口方法是否实际上是标记为override的方法

这不是有点误导吗<代码>覆盖
意味着有一个基类定义被覆盖。将其定义为:

重写修饰符是扩展或修改继承的方法、属性、索引器或事件的抽象或虚拟实现所必需的

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

覆盖继承的行为意味着:

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

那么,在查看类实现时,除了//注释之外,是否有其他方法指示此方法实现了某个接口的方法

事实上,是的。你可以。大概是这样的:

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

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

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

类中可能有多个特定接口的实现。哪些方法应该标记为“重写”?@DEnnis-你是说当两个接口拥有一个具有相同签名的方法,而类同时实现了这两个方法时?好吧,首先,你不重写接口方法。接口没有实际的方法,只有它们的定义。您可以实现这些方法。基类“
virtual
方法”有一个实际的实现,您可能希望也可能不希望覆盖它。由于接口方法是“重写的”,我想需要
override
关键字会有点误导…@David嗯,抽象成员需要
override
。。。它们只是签名:DFWIW:ReSharper在实现接口成员的成员面前显示一个小图标。可能还有其他外接程序。但是没有“普通”的c#/.Net way.Upvote来提及显式实现——这似乎是询问者想要的约定(我也在寻找)。但是,应该删除“public”访问修饰符-显然它是由显式实现强制执行的