对于接口,添加abstract
的,甚至public
关键字是多余的,所以你忽略它们:
interface MyInterface {
void Method();
}
在CIL,该方法被标记virtual
和abstract
。
(请注意,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 { }
如果Base
和Derived
在同一组件声明,编译器将使Base::Method
虚拟并密封(在CIL中),尽管Base
没有实现该接口。
如果Base
和Derived
在不同的组件,编译Derived
组装时,编译器将不会改变其他组件,因此它会引入Derived
的成员,这将是一个明确的实施MyInterface::Method
,这将只是委托致电Base::Method
。
所以你看,每接口方法的实现必须支持多态行为,因此必须标注在CIL虚拟,即使编译器必须经过箍做到这一点。
因为它们被声明为接口 – 2010-09-01 19:22:21
@Muad:请参阅我的编辑。 – 2010-09-01 19:24:49