C # - вызов метода в базовом классе - PullRequest
3 голосов
/ 19 августа 2011

У меня есть 2 класса:

public class A
{
    public void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
}

public class B : A
{
    public new void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
}

В своем коде я делаю следующее:

B writeClass = new B();
writeClass.WriteLine("Output"); // I expect to see 'Output from B'
A otherClass = (A)writeClass;
otherClass.WriteLine("Output"); // I expect to see just 'Output'

Я предполагал, что это сработает из-за полиморфизма .

Однако, он всегда пишет «Вывод из B» каждый раз. Есть ли способ заставить это работать так, как я хочу?

РЕДАКТИРОВАТЬ Пример кода исправления.

Ответы [ 6 ]

5 голосов
/ 19 августа 2011

Когда вы «скрываете» метод от базового класса с помощью NEW, вы просто его скрываете, вот и все.Он по-прежнему вызывается, когда вы явно вызываете реализацию базового класса.

A не содержит WriteLine, поэтому вам нужно это исправить.Когда я исправил это, я получил

Output from B
Output


namespace ConsoleApplication11
{
    class Program
    {
        static void Main(string[] args)
        {
            B writeClass = new B(); 
            writeClass.WriteLine("Output"); // I expect to see 'Output from B' 
            A otherClass = (A)writeClass; 
            otherClass.WriteLine("Output"); // I expect to see just 'Output' 
            Console.ReadKey();
        }
    }

    public class A
    {
        public void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
    }
    public class B : A
    {
        public new void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
    }
}
1 голос
/ 19 августа 2011

Ваш метод в классе A - это Write, а не WriteLine.Измените его на то же имя, и оно будет работать так, как вы ожидаете.Я только что попробовал и получил:

Output from B
Output

Полиморфизм (Руководство по программированию в C #) объясняет это довольно хорошо.(Это более новая версия исходной ссылки автора.) На странице показаны примеры, когда производный класс переопределяет виртуальный член и где новые члены скрывают членов базового класса.

По-видимому, существует некоторая путаница с новым модификатором.,Из документации :

Хотя вы можете скрывать элементы без использования нового модификатора, результатом будет предупреждение.Если вы используете new для явного скрытия члена, он подавляет это предупреждение и документирует тот факт, что производная версия предназначена для замены.

Обратите внимание, что скрытый член не обязательно должен быть виртуальным.

Лучшие практики:

  • Настоятельно предпочитайте переопределение сокрытию.Полиморфные вызовы идиоматичны на языках ОО.
  • Если вы хотите скрыть член, всегда используйте новый модификатор.
  • Никогда не выпускайте код с предупреждениями компилятора.
  • Если каждый разработчик в вашей команде согласен с тем, что предупреждение компилятора не может быть исправлено, отключите его.
0 голосов
/ 19 августа 2011

Во-первых: я думаю, что вы хотели назвать оба метода «WriteLine», но тот, что в классе A, называется только «Write».И второе: да, вы наследуете B от A, но объект по-прежнему будет иметь тип «B», так что теперь я не думаю, что то, что вы хотите, возможно.

0 голосов
/ 19 августа 2011

Ваш класс А имеет функцию записи вместо WriteLine

public class A
{
    public virtual void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
}

public class B : A
{
    public override void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
}
0 голосов
/ 19 августа 2011

Ключевое слово "new" делает реализацию B реализацией перезаписи A в WriteLine.

Не принимайте это как ответ, но, по моему опыту, использование ключевого слова "new" почти всегда является ошибкой.таким образом.Это менее читабельно и мутно - ясность вашего кода.

0 голосов
/ 19 августа 2011

Не используйте ключевое слово new при переопределении метода в классе B.И объявить метод в A как virtual.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...