为什么C#接口方法没有声明为抽象或虚拟的?

接口中的C#方法在不使用virtual关键字的情况下被声明,并且在派生类中被覆盖而未使用override关键字。

是否有一个原因?我认为这只是一种语言上的便利,显然CLR知道如何在后台进行处理(默认情况下方法不是虚拟的),但是还有其他技术原因吗?

这是派生类生成的IL:

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

请注意,该方法virtualfinal在IL中声明。

回答:

对于该接口,添加abstract甚至public关键字是多余的,因此您可以省略它们:

interface MyInterface {

void Method();

}

在CIL中,该方法被标记为virtualabstract

(请注意,Java允许声明接口成员public abstract)。

对于实现类,有一些选项:

:在C#中,类未将方法声明为virtual。这意味着它不能在派生类中被覆盖(只能是隐藏的)。在CIL中,该方法仍然是虚拟的(但是封闭的),因为它必须支持有关接口类型的多态性。

class MyClass : MyInterface {

public void Method() {}

}

:在C#和CIL中,方法均为virtual。它参与多态调度,可以被覆盖。

class MyClass : MyInterface {

public virtual void Method() {}

}

:这是类实现接口的一种方法,但不提供类本身的公共接口中的接口方法。在CIL中,该方法将是private(!),但仍然可以从类外部通过对相应接口类型的引用进行调用。显式实现也是不可覆盖的。这是可能的,因为有一个CIL指令(.override)将私有方法链接到它正在实现的相应接口方法。

[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中,您甚至可以在实现类中为接口方法名称加上别名。

[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

}

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

interface MyInterface {

void Method();

}

class Base {

public void Method();

}

class Derived : Base, MyInterface { }

如果BaseDerived在同一程序集中声明,则编译器将Base::Method虚拟化并密封化(在CIL中),即使Base未实现该接口也是如此。

如果BaseDerived在不同的程序集中,则在编译该Derived程序集时,编译器不会更改其他程序集,因此它将引入一个成员,Derived该成员将是一个显式实现MyInterface::Method,将其委托给Base::Method

因此,您将看到, 每个 接口方法实现都必须支持多态行为,因此即使编译器必须经过箍才能实现,也必须在CIL上将其标记为虚拟。

以上是 为什么C#接口方法没有声明为抽象或虚拟的? 的全部内容, 来源链接: utcz.com/qa/402227.html

回到顶部