2008-12-23 76 views
4

我有一个带有虚拟方法的基类以及覆盖该方法的多个子类。C#调用被重写的子类方法,但不知道它是子类实例

当我遇到这些子类之一时,我想调用重写的方法,但不知道子类。我可以想到丑陋的方法来做到这一点(检查一个值并进行转换),但似乎应该有一种用语言来表达的方式。我希望List在同一个列表中包含多个子类,否则显然我只能创建一个List。

编辑:修正了,这是错误的代码,导致非常合适的第一个答案我:)

例如评论,:

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 
} 
+0

如何打印Foo,如果它是派生类重写虚拟方法?在你的代码示例中错字? – mmcrae 2015-06-24 15:48:41

回答

8
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 
} 
+0

这是我想要的行为,但没有得到..我的问题竟然是加载旧的基类类型的旧序列化对象,而不是新的子类。 – 2008-12-23 23:28:47

1

为什么它应打印“富”?这不是虚拟方法的目的。整个观点是派生类可以在不改变接口的情况下改变函数的工作方式。 Foo对象将打印“Foo”,而Bar对象将打印“Bar”。还有其他什么是错的。

+0

你是对的。我原本发布的代码段中的评论中存在一个错误。它调用基类方法,大概是因为它不知道它是一个子类实例。 – 2008-12-23 23:22:28

0

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

欲了解更多信息请点击这里:http://geekswithblogs.net/Mohamed/articles/28613.aspx

0

为了获得在这种情况下,你想要的行为,你可以删除该虚拟基类和子类使用新的。

但是,就像埃德斯旺格表示,你为什么?

0

是不是有一个解决方案,你只投你要调用另一个对象:

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

成为

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

还是我失去了这个问题的某些部分?

+1

第二个会调用printMe并尝试将返回值转换为(Foo)。它返回无效。 – 2008-12-24 00:00:00

相关问题