new virtual functions

H

headware

I have a question about the use of the "new" and "virtual" keywords
together. Say I have the following four classes

class A {
virtual public void f() {
System.Console.WriteLine("A.f()");
}
}

class B : A {
override public void f() {
System.Console.WriteLine("B.f()");
}
}

class C : B {
new virtual public void f() {
System.Console.WriteLine("C.f()");
}
}

class D : C {
override public void f() {
System.Console.WriteLine("D.f()");
}
}

and I use them like this:

class Test {
[STAThread]
static void Main(string[] args) {
C cRef = new D();
cRef.f(); //prints out "D.f()"

A aRef = new D();
aRef.f(); //prints out "B.f()"?!
}
}

It makes sense to me that cRef.f() prints out "D.f()", that is basic
polymorphism. What doesn't make that much sense to me is why aRef.f()
prints out "B.f()". Why should a reference of type A pointing to an
object of type D call B.f()? I realize that it has to do with the fact
that f() is declared as new virtual in C. What I don't understand is
why this is the correct behavior. Why would you even want to do
something like this? How could this be used?

Thanks,
Dave
 
J

Jon Skeet [C# MVP]

It makes sense to me that cRef.f() prints out "D.f()", that is basic
polymorphism. What doesn't make that much sense to me is why aRef.f()
prints out "B.f()". Why should a reference of type A pointing to an
object of type D call B.f()? I realize that it has to do with the fact
that f() is declared as new virtual in C. What I don't understand is
why this is the correct behavior. Why would you even want to do
something like this? How could this be used?

B.f() overrides A.f(), which is basically what you're calling when you
use aRef.f(). C.f() and D.f() are completely separate methods to A.f()
and B.f() as far as the compiler is concerned.

As for why/when you'd want to use it - very rarely, basically. The
usual situation would be if you've got a library class and a class
you've derived from it. You've put in a method called Foo(), and then
in the next version of the library that class gains a method called
Foo() as well, which might be meant to do something completely
different. You don't want to override the library class's Foo() method,
because then the library class would be expecting it to do one thing
and it would actually do another, but you still want your code which
uses your Foo() method to compile and run properly.
 
H

headware

I see. You're right, that doesn't seem like something you would use too
often, but that does solve the problem you mentioned. Thanks for the
reply.

Dave
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top