tags:

views:

886

answers:

5

I was looking at this question and I was wondering whether every abstract function should be considered to be a virtual function in C# or in general?

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. Virtual functions have a compile-time dimension too, in that you cannot override a non-virtual function, but is mostly a runtime concept since it is "just" the selection of the correct method implementation based on the actual receiver.

A: 

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 */ }
}
Marc Gravell
+1  A: 

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)

Quaky
+13  A: 

Yes. From section 10.6.6 of the C# 3.0 spec:

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.

Jon Skeet
You can't get a better answer than pulling out the C# spec. :)
Quibblesome
A: 

I think you are looking at the problem from a "C++" point of view (be terse, avoid necessary keywords, save keystrokes).

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.

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.

James Curran
+1  A: 

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. For example, given the classic Animal hierarchy:

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.

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.

P Daddy
Abstract methods don't NEED to be virtual, they could have provided another keyword that simply implemented it in the concrete class, but didn't allow subclasses to further override it.
Matthew Scharley
@Matthew Scharley: Yes they need to be virtual. A concrete derivative can seal its implementation, preventing overriding by further derivatives, but that doesn't make the function any less virtual. Calls still go through the v-table, and a call through to the base class will still call the derived class's function.
P Daddy