简体   繁体   English

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

[英]Is every abstract function virtual in C#, in general?

I was looking at Stack Overflow question What is the difference between abstract function and virtual function? 我在看Stack Overflow问题抽象函数和虚函数有什么区别? , and I was wondering whether every abstract function should be considered to be a virtual function in C# or in general? ,我想知道每个抽象函数是否应该被认为是C#中的虚函数或者一般?

I was a bit puzzled by the "you must override/you may override" responses to that question. 我对“你必须覆盖/你可以覆盖”对这个问题的回答感到有些困惑。 Not being a C# programmer, I tend to think that abstract functions are a compile-time concept only, and that abstract functions are virtual functions by definition since you must provide at least one but can provide multiple implementations further down the hierarchy. 不是C#程序员,我倾向于认为抽象函数只是一个编译时的概念,抽象函数是定义的虚函数,因为你必须提供至少一个,但可以在层次结构的下面提供多个实现。

Virtual functions have a compile-time dimension too, in that you cannot override a non-virtual function, but they are mostly a runtime concept since it is "just" the selection of the correct method implementation based on the actual receiver. 虚函数也具有编译时维度,因为您不能覆盖非虚函数,但它们主要是运行时概念,因为它“只是”选择基于实际接收器的正确方法实现。

Yes. 是。 From section 10.6.6 of the C# 3.0 spec : C#3.0规范的第10.6.6节:

When an instance method declaration includes an abstract modifier, that method is said to be an abstract method. 当实例方法声明包含一个抽象修饰符时,该方法被称为抽象方法。 Although an abstract method is implicitly also a virtual method, it cannot have the modifier virtual. 虽然抽象方法也隐式也是虚方法,但它不能具有虚拟修饰符。

It has to be virtual (and Jon Skeet has already whipped out the spec to prove that it is ), because, given a reference to the abstract base class, the concrete derived class's implementation must be called. 必须是虚拟的(并且Jon Skeet已经完成了规范以证明它 ),因为,在给定抽象基类的引用时,必须调用具体的派生类的实现。 For example, given the classic Animal hierarchy: 例如,给定经典的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");}
}

A function that takes an Animal object, and calls its Speak method wouldn't know which implementation to call if the function weren't virtual. 如果函数不是虚拟的,那么接受Animal对象并调用其Speak方法的函数将不知道要调用哪个实现。

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

Note however, that interface implementations are not virtual by default. 但请注意,默认情况下,接口实现不是虚拟的。 Because an interface works differently from a class, true polymorphism isn't necessary to find the implementation of an interface method. 因为接口与类的工作方式不同,所以不需要真正的多态来查找接口方法的实现。

Yes, it is. 是的。 For proof: 证明:

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 */ }
}

Yes. 是。

An abstract property declaration specifies that the accessors of the property are virtual, but does not provide an actual implementation of the accessors. 抽象属性声明指定属性的访问器是虚拟的,但不提供访问器的实际实现。 ( MSDN ) MSDN

I think you are looking at the problem from a "C++" point of view (be terse, avoid necessary keywords, save keystrokes). 我认为你从“C ++”的角度来看问题(简洁,避免必要的关键字,保存击键)。

The C# philosophy is the the intent of the code should be clear from reading the source, and the compiler should be able to verify that intention as much as possible. C#的理念是代码的意图应该从阅读源中清楚,并且编译器应该能够尽可能地验证该意图。

So, while there is very little different in the generated MSIL between an abstract method and a virtual method (or for that matter, between an abstract and a non-abstract class; or between an out parameter and a ref parameter), the extra keywords do tell maintenance programmers something, and allow the compiler the double check what you are doing. 因此,虽然抽象方法和虚方法之间生成的MSIL之间几乎没有什么不同(或者就此而言,在抽象和非抽象类之间;或在out参数和ref参数之间),额外的关键字告诉维护程序员一些东西,并让编译器仔细检查你在做什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM