C# 在不知道它是子类实例的情况下调用重写的子类方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/390326/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 01:40:10  来源:igfitidea点击:

C# calling overridden subclass methods without knowledge that it's a subclass instance

c#inheritancevirtualoverridingsubclass

提问by John Noonan

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.

当我遇到这些子类之一时,我想调用重写的方法,但不知道子类。我可以想到丑陋的方法来做到这一点(检查一个值并转换它),但似乎应该有一种语言中的方法来做到这一点。我希望 List 在同一个列表中包含多个子类,否则显然我可以制作一个 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
} 

采纳答案by Daniel Earwicker

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
}

回答by Ed S.

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.

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

回答by Manu

Use the newmodifier 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.

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

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

有关更多信息,请访问:http: //geekswithblogs.net/Mohamed/articles/28613.aspx

回答by toad

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

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

However, like Ed Swangren indicated, why would you?

然而,就像 Ed Swangren 指出的那样,你为什么要这样做?

回答by JB King

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?

或者我错过了问题的某些部分?