一般来说,每个抽象函数在C#中都是虚拟的吗?

我在看Stack Overflow问题抽象函数和虚函数有什么区别? ,我想知道每个抽象函数是否应该被认为是C#中的虚函数或者一般?

我对“你必须覆盖/你可以覆盖”对这个问题的回答感到有些困惑。 不是C#程序员,我倾向于认为抽象函数只是一个编译时的概念,抽象函数是定义的虚函数,因为你必须提供至少一个,但可以在层次结构的下面提供多个实现。

虚函数也有编译时维度,因为你不能覆盖非虚函数,但它们主要是运行时概念,因为它“只是”选择基于实际接收器的正确方法实现。

是。 从C#3.0规范的第10.6.6节:

当实例方法声明包含一个抽象修饰符时,该方法被称为抽象方法。 虽然抽象方法也隐式地也是虚方法,但它不能具有虚拟修饰符。

必须是虚拟的(并且Jon Skeet已经完成了规范以certificate它 ),因为,在给出对抽象基类的引用时,必须调用具体派生类的实现。 例如,给定经典的Animal层次结构:

abstract class Animal{ public abstract void Speak(); } class Cat : Animal{ public override void Speak(){Console.WriteLine("meow");} } class Dog : Animal{ public override void Speak(){Console.WriteLine("bark");} } 

如果函数不是虚拟的,那么接受Animal对象并调用其Speak方法的函数将不知道要调用哪个实现。

 static void TalkToAnimal(Animal a){ Console.WriteLine("Hello, animal."); a.Speak(); } 

但请注意,默认情况下,接口实现不是虚拟的。 因为接口与类的工作方式不同,所以不需要真正的多态来查找接口方法的实现。

是的。 certificate:

 abstract class A { public abstract void Foo(); } class B : A { public override void Foo() { /* must do */ } } class C : B { public override void Foo() { /* can do */ } } 

是。

抽象属性声明指定属性的访问器是虚拟的,但不提供访问器的实际实现。 ( MSDN )

我认为你从“C ++”的角度来看问题(简洁,避免必要的关键字,保存击键)。

C#的理念是代码的意图应该从阅读源中清楚,并且编译器应该能够尽可能地validation该意图。

因此,虽然生成的MSIL在抽象方法和虚方法之间(或者就此而言,在抽象类和非抽象类之间;或者在out参数和ref参数之间)之间几乎没有什么不同,但是额外的关键字告诉维护程序员一些东西,并让编译器仔细检查你在做什么。