Реальное использование нового ключевого слова, чтобы скрыть реализацию виртуального метода? C # - PullRequest
6 голосов
/ 29 июля 2011

Каков реальный сценарий, в котором мы будем использовать new, чтобы обеспечить новую реализацию для виртуального метода в производном классе?C #

Я знаю, что это означает технически.я ищу сценарий из реальной жизни, где это будет необходимо.

Мы всегда можем добиться того же, предоставляя функцию переопределения.Почему мы хотим, чтобы неправильный метод выбирался, когда вызывается метод, приведенный к базе.

Ответы [ 3 ]

5 голосов
/ 29 июля 2011

Нет, вы не можете добиться того же, переопределив:

  • Указание нового метода позволяет изменять тип возвращаемого значения
  • Вызов базыМетод не может быть неправильным

Один пример сценария:

  • Вы используете стороннюю библиотеку Foo, которая содержит класс FooBase
  • Вы пишете свой собственный подкласс Foo, Bar
  • Вы вводите публичный метод в Bar под названием DoSomething
  • В следующей версии Foo третья сторона представляет метод DoSomething в Foo, которыйне делает то же самое, что ваш метод.Это может быть или не быть виртуальным.

На этом этапе вы хотите, чтобы весь ваш существующий код вызывал Bar.DoSomething, чтобы все еще вызывал Bar.DoSomething,но весь код, который вызывает Foo.DoSomething, должен по-прежнему вызывать эту реализацию - эти вызывающие стороны могут даже не знать о вашем методе, и они могут быть в сторонней сборке.

В долгосрочной перспективеВ этом случае вы, возможно, захотите переименовать свой метод, если сможете (в зависимости от степени контроля над вызывающими объектами), но в краткосрочной перспективе, если ваш метод как new достигнет именно того поведения, которое вы хотите.

Такие вещи иногда называют проблемой хрупкого базового класса .Эрик Липперт написал об этом достаточно много, в том числе этот пост еще в 2004 году .

5 голосов
/ 29 июля 2011

Нет.Вы не можете достичь того же.

// 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.

----------

ПереопределитьВСЕГДА переопределяет, в то время как new работает ТОЛЬКО, когда используется как объявленный тип (не базовый).

Вы можете увидеть больше здесь

0 голосов
/ 04 февраля 2015

Виртуальный метод может быть переопределен. Ключевое слово virtual обозначает метод, который переопределяется в производных классах. Мы можем добавлять производные типы без изменения остальной части программы. Таким образом, тип объектов во время выполнения определяет поведение.

...