Question

I have a base class with a virtual method, and multiple subclasses that override that method.

When I encounter one of those subclasses, I would like to call the overridden method, but without knowledge of the subclass. I can think of ugly ways to do this (check a value and cast it), but it seems like there should be an in-language way to do it. I want the List to contain multiple subclasses within the same list, otherwise obviously I could just make a List.

EDIT: Fixed the comment in the code that was wrong, which lead to the very appropriate first answer I got :)

For instance:

Class Foo 
{
    public virtual printMe()
    {
        Console.Writeline("FOO");
    }
}

Class Bar : Foo 
{
    public override printMe()
    {
        Console.Writeline("BAR");
    }
}

List<Foo> list = new List<Foo>();
// then populate this list with various 'Bar' and other overriden Foos

foreach (Foo foo in list) 
{
    foo.printMe(); // prints FOO.. Would like it to print BAR
} 
Was it helpful?

Solution

class Foo 
{
    public virtual void virtualPrintMe()
    {
        nonVirtualPrintMe();
    }

    public void nonVirtualPrintMe()
    {
        Console.Writeline("FOO");
    }
}

class Bar : Foo 
{
    public override void virtualPrintMe()
    {
        Console.Writeline("BAR");
    }
}

List<Foo> list = new List<Foo>();
// then populate this list with various 'Bar' and other overriden Foos

foreach (Foo foo in list) 
{
    foo.virtualPrintMe(); // prints BAR or FOO
    foo.nonVirtualPrintMe(); // always prints FOO
}

OTHER TIPS

Why should it print "Foo"? That is not the purpose of virtual methods. The whole point is that the derived classes can change the way the function works without changing the interface. A Foo object will print "Foo" and a Bar object will print "Bar". Anything else would be wrong.

Use the new modifier to explicitly hide a member inherited from a base class. To hide an inherited member, declare it in the derived class using the same name, and modify it with the new modifier. This will result in exactly the behavior you want.

For more info go here: http://geekswithblogs.net/Mohamed/articles/28613.aspx

To get the behavior you want in this situation you could remove the virtual on the base class and use new on the subclass.

However, like Ed Swangren indicated, why would you?

Isn't there a solution where you just cast the object you want to call the other one:

 foo.printMe(); // prints FOO.. Would like it to print BAR

becomes

(Foo)foo.printMe(); // foo can be any derived class of Foo.

Or am I missing some part of the question?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top