4

我有一个带有虚拟方法的基类,以及覆盖该方法的多个子类。

当我遇到其中一个子类时,我想调用被覆盖的方法,但不知道子类。我可以想出丑陋的方法来做到这一点(检查一个值并强制转换它),但似乎应该有一种语言内的方法来做到这一点。我希望列表在同一个列表中包含多个子类,否则显然我可以创建一个列表。

编辑:修复了代码中错误的注释,这导致我得到了非常合适的第一个答案:)

例如:

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
} 
4

5 回答 5

9
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
}
于 2008-12-23T23:18:56.517 回答
1

为什么要打印“Foo”?这不是虚方法的目的。关键是派生类可以在不改变接口的情况下改变函数的工作方式。Foo 对象将打印“Foo”,而 Bar 对象将打印“Bar”。其他任何事情都是错误的。

于 2008-12-23T23:15:09.880 回答
0

使用new修饰符显式隐藏从基类继承的成员。要隐藏继承的成员,请在派生类中使用相同的名称声明它,并使用 new 修饰符对其进行修改。这将导致您想要的行为。

欲了解更多信息,请访问:http: //geekswithblogs.net/Mohamed/articles/28613.aspx

于 2008-12-23T23:18:01.463 回答
0

要在这种情况下获得您想要的行为,您可以删除基类上的 virtual 并在子类上使用 new 。

但是,就像 Ed Swangren 指出的那样,您为什么要这样做?

于 2008-12-23T23:19:59.963 回答
0

是否有一种解决方案,您只需将要调用的对象转换为另一个对象:

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

变成

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

还是我错过了问题的某些部分?

于 2008-12-23T23:31:42.153 回答