现实生活中使用 new 关键字来隐藏虚拟方法实现?时间:2019-03-17 标签:c#

发布于 11-27 01:42 字数 154 浏览 2 评论 0原文

在现实生活中,我们将使用 new 为派生类中的虚拟方法提供新的实现是什么? C#

我知道它在技术上意味着什么。我正在寻找的是一个需要这样做的现实生活场景。

我们总是可以通过提供覆盖功能来实现相同的目的。当方法调用被强制转换为基类时,为什么我们要选择不正确的方法。

What's the real life scenario where we will use new to provide new implementation for a virtual method in the derived class? C#

I know what it means technically. what I am looking for is a real life scenario where this will be needed.

We can always achieve the same by providing the override functionality. Why would we want to incorrect method been picked when methods call is made casted to base.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

深空失忆2024-12-04 01:42:33

不,你无法实现同样的目标。

// Define the base class
class Car
{
    public virtual void DescribeCar()
    {
        System.Console.WriteLine("Four wheels and an engine.");
    }
}

// Define the derived classes
class ConvertibleCar : Car
{
    public new virtual void DescribeCar()
    {
        base.DescribeCar();
        System.Console.WriteLine("A roof that opens up.");
    }
}

class Minivan : Car
{
    public override void DescribeCar()
    {
        base.DescribeCar();
        System.Console.WriteLine("Carries seven people.");
    }
}

现在,如果您尝试执行此操作:

public static void TestCars2()
{
    Car[] cars = new Car[3];
    cars[0] = new Car();
    cars[1] = new ConvertibleCar();
    cars[2] = new Minivan();
}

结果将是:

Car object: YourApplication.Car

Four wheels and an engine.

----------

Car object: YourApplication.ConvertibleCar

Four wheels and an engine.

----------

Car object: YourApplication.Minivan

Four wheels and an engine.

Carries seven people.

----------

Override 始终覆盖,而 new 仅在用作其声明类型(而不是基类型)时才执行。

您可以在此处查看更多信息

No. You can't achieve the same.

// Define the base class
class Car
{
    public virtual void DescribeCar()
    {
        System.Console.WriteLine("Four wheels and an engine.");
    }
}

// Define the derived classes
class ConvertibleCar : Car
{
    public new virtual void DescribeCar()
    {
        base.DescribeCar();
        System.Console.WriteLine("A roof that opens up.");
    }
}

class Minivan : Car
{
    public override void DescribeCar()
    {
        base.DescribeCar();
        System.Console.WriteLine("Carries seven people.");
    }
}

Now, if you try to do this:

public static void TestCars2()
{
    Car[] cars = new Car[3];
    cars[0] = new Car();
    cars[1] = new ConvertibleCar();
    cars[2] = new Minivan();
}

The result will be:

Car object: YourApplication.Car

Four wheels and an engine.

----------

Car object: YourApplication.ConvertibleCar

Four wheels and an engine.

----------

Car object: YourApplication.Minivan

Four wheels and an engine.

Carries seven people.

----------

Override ALWAYS override while new ONLY does it when is used as its declared type (not base one).

You can see more here

苏辞2024-12-04 01:42:33

不,您不能通过重写来实现相同的目的:

  • 指定新方法允许您改变返回类型
  • 调用基本方法可能不会不正确

一个示例场景:

  • 您正在使用第 3 方库 Foo,其中包含类 FooBase
  • 您编写自己的 Foo 子类,Bar
  • 您在 Bar 中引入了一个名为 DoSomething 的公共方法
  • 在 Foo 的下一个版本中,第 3 方在 Foo 中引入了一个 DoSomething 方法,该方法与你的方法不一样。这可能是也可能不是虚拟的。

此时,您希望调用 Bar.DoSomething 的所有现有代码仍然调用 Bar.DoSomething,但所有调用 Foo.DoSomething 的代码仍应调用该实现 -这些调用者甚至可能不知道您的方法,并且他们可能位于第三方程序集中。

从长远来看,在这种情况下,如果可以的话,您可能希望重命名您的方法(取决于您对调用者的控制程度),但从短期来看,将您的方法设置为 new 可以完全实现你想要的行为。

这类问题有时被称为“脆弱基类”问题。 Eric Lippert 已经写了相当广泛的文章,包括

No, you can't achieve the same by overriding:

  • Specifying a new method allows you to vary the return type
  • Calling the base method may not be incorrect

One example scenario:

  • You're using 3rd party library Foo, which contains a class FooBase
  • You write your own subclass of Foo, Bar
  • You introduce a public method in Bar called DoSomething
  • In the next version of Foo, the 3rd party introduces a DoSomething method in Foo which doesn't do the same as your method. This may or may not be virtual.

At this point, you want all your existing code calling Bar.DoSomething to still call Bar.DoSomething, but all the code which calls Foo.DoSomething should still call that implementation - those callers may not even know about your method, and they may be in the third party assembly.

In the long term in that situation you would probably want to rename your method if you can (depending on how much control you have over your callers) but in the short term, making your method as new achieves exactly the behaviour you want.

This sort of thing is sometimes known as the brittle base class problem. Eric Lippert has written about it reasonably extensively, including this post back in 2004.

白首有我共你2024-12-04 01:42:33

可以重新定义虚方法。 virtual 关键字指定在派生类中重写的方法。我们可以添加派生类型,而无需修改程序的其余部分。因此,对象的运行时类型决定了行为。

A virtual method can be redefined. The virtual keyword designates a method that is overridden in derived classes. We can add derived types without modifying the rest of the program. The runtime type of objects thus determines behavior.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文