C# 编译器要求将用于实现一个接口的方法标记为public . CLR要求将接口方法标记为virtual. 如果在源代码中没有显示地将方法标记为virtual, 编译器会将它们标记为virtual和sealed; 这会阻止派生类重写接口方法。如果显式地将方法标记为virtual, 编译器就会将该方法标记为virtual(并保持它的密封状态)。这样一来。派生类就能重写它。
如果一个接口方法是sealed的,派生类就不能重写它。不过派生类可以重新继承同一个接口,并可为该接口的方法提供它自己的实现。在一个对象上调用一个接口的方法时,将调用该方法在该对象的类型中的实现。
隐式和显示接口方法实现
一个类型加载到CLR中时,会为该类型创建并初始化一个方法表。在这个方法表中,类型引入的每个新方法都有一条对应的记录项;另外,还为该类型继承的所有虚方法添加了记录项。继承的虚方法既有有继承层次结构中的各个基类型定义的,也有由接口类型定义的。所以,对于下面这样的一个简单类型定义:
internal sealed class SimpleType : IDisposable{
public void Dispose(){
Console.WriteLine("Dispose");
}
}
类型的方法表将包含与一下方法对应的记录项。
1,object定义的所有虚实例方法。
2,IDisposable 定义的所有接口方法,本例只有一个方法,即Dispose, 因为IDisposable 接口只定义了这个方法。
3,SimpleType引入的新方法 Dispose
泛型接口的好处:
1,泛型接口提供了出色的编译时类型安全性。
2,处理值类型时,装箱次数会少得多。
3,类可以实现同一个接口若干次,只要每次使用不同类型参数。
接口的泛型类型参数可标记为逆变和协变,从而为泛型接口的使用赋予更大的灵活性。
接口约束,C#编译器会生成特定的IL指令,这些指令导致直接在值类型上调用接口方法,不对其进行装箱。如果不使用接口约束,就没有其他办法让C#编译器生成这些IL指令,如此一来,在值类型上调用接口方法总是会造成装箱。
(一个例外是如果值类型实现了一个接口方法,那么在值类型的实例上调用了这个方法并不会造成值类型的实例装箱。)
接口和基类的区别
Can do 和 Is-A的区别。