为什么C#接口中的方法不声明抽象的或虚拟的? [英] Why are C# interface methods not declared abstract or virtual?

查看:136
本文介绍了为什么C#接口中的方法不声明抽象的或虚拟的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C#方法声明不使用虚拟关键字,并且无需使用覆盖关键字。

C# methods in interfaces are declared without using the virtual keyword, and overridden in the derived class without using the override keyword.

有一个原因?我认为这只是一门语言的便利,明明CLR知道如何盖(方法是不是默认虚拟)下处理这个问题,但是否有其他技术原因?

Is there a reason for this? I assume that it is just a language convenience, and obviously the CLR knows how to handle this under the covers (methods are not virtual by default), but are there other technical reasons?

下面是IL派生类生成:

Here is the IL that a derived class generates:

class Example : IDisposable {
    public void Dispose() { }
}

.method public hidebysig newslot virtual final 
        instance void  Dispose() cil managed
{
  // Code size       2 (0x2)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ret
} // end of method Example::Dispose

请注意,该方法被声明虚拟 最后中的白细胞介素。

推荐答案

有关在接口方面,除了在摘要,甚至公开关键字是多余的,所以你忽略它们:

For the interface, the addition of the abstract, or even the public keywords would be redundant, so you omit them:

interface MyInterface {
  void Method();
}

在CIL,该方法被标记虚拟摘要

In the CIL, the method is marked virtual and abstract.

(注意,Java允许声明接口成员公共抽象)。

(Note that Java allows interface members to be declared public abstract).

有关实现类,还有一些选项:

For the implementing class, there are some options:

非重写:在C#中的类未声明的方法虚拟。这意味着它不能在派生类(仅隐藏)覆盖。在CIL的方法仍然是虚拟的(但密封),因为它必须支持对接口类型多态。

Non-overridable: In C# the class doesn't declare the method as virtual. That means that it cannot be overridden in a derived class (only hidden). In the CIL the method is still virtual (but sealed) because it must support polymorphism regarding the interface type.

class MyClass : MyInterface {
  public void Method() {}
}

可重写:无论是在C#和在CIL的方法是虚拟。它参与多态的调度,它可以被覆盖。

Overridable: Both in C# and in the CIL the method is virtual. It participates in polymorphic dispatch and it can be overridden.

class MyClass : MyInterface {
  public virtual void Method() {}
}

明确:这是一个类实现一个接口,但没有提供在类中的公共接口的接口方法的一种方式。在CIL的方法将是私人(!),但它仍然是从类的外部调用从到相应的接口类型的引用。明确的实现也是非重写。这可能是因为有一个CIL指令( .override ),将私有方法链接到它的实现相应的接口方法。

Explicit: This is a way for a class to implement an interface but not provide the interface methods in the public interface of the class itself. In the CIL the method will be private (!) but it will still be callable from outside the class from a reference to the corresponding interface type. Explicit implementations are also non-overridable. This is possible because there's a CIL directive (.override) that will link the private method to the corresponding interface method that it's implementing.

[C#]

class MyClass : MyInterface {
  void MyInterface.Method() {}
}

[CIL]

.method private hidebysig newslot virtual final instance void MyInterface.Method() cil managed
{
  .override MyInterface::Method
}

在VB.NET,你甚至可以别名实现类的接口方法的名称。

In VB.NET, you can even alias the interface method name in the implementing class.

[VB.NET]

Public Class MyClass
  Implements MyInterface
  Public Sub AliasedMethod() Implements MyInterface.Method
  End Sub
End Class

[CIL]

.method public newslot virtual final instance void AliasedMethod() cil managed
{
  .override MyInterface::Method
}

现在,考虑这种怪异的情况:

Now, consider this weird case:

interface MyInterface {
  void Method();
}
class Base {
  public void Method();
}
class Derived : Base, MyInterface { }

如果基本派生在同一个组件声明,编译器将基地::方法虚拟和密封(在CIL),即使基本未实现的接口。

If Base and Derived are declared in the same assembly, the compiler will make Base::Method virtual and sealed (in the CIL), even though Base doesn't implement the interface.

如果基本派生在不同的组件,编译时的导出组装,编译器将不会改变其他装配,因此它会引入一个成员导出这将是 MyInterface的方法:: 将委派只是调用基础::方法

If Base and Derived are in different assemblies, when compiling the Derived assembly, the compiler won't change the other assembly, so it will introduce a member in Derived that will be an explicit implementation for MyInterface::Method that will just delegate the call to Base::Method.

所以你看,的每个的接口方法的实现必须支持多态行为,因此必须标注在CIL虚,即使编译器必须经过箍做到这一点。

So you see, every interface method implementation must support polymorphic behavior, and thus must be marked virtual on the CIL, even if the compiler must go through hoops to do it.

这篇关于为什么C#接口中的方法不声明抽象的或虚拟的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆