2012-10-04 18 views
6

Скажем, у меня есть абстрактный родительский класс с именем «Родитель», который реализует метод «DisplayTitle». Я хочу, чтобы этот метод был одинаковым для каждого подкласса, который наследует «родительский». Я хотел бы получить ошибку компиляции, если подкласс пытается реализовать свой собственный метод «DisplayTitle». Как это сделать на C#. Я верю в Java, я бы просто отметил метод как «final», но я не могу найти альтернативы в C#. Я возился с «запечатанными» и «отмененными», но я не могу получить поведение, которое я ищу.Предотвращение подкласса C# от перезаписи метода

Например, в этом коде:

using System; 

namespace ConsoleApplication1 
{ 
    class Parent 
    { 
     public void DisplayTitle() { Console.WriteLine("Parent's Title"); } 
    } 

    class ChildSubclass : Parent 
    { 
     public void DisplayTitle() { Console.WriteLine("Child's Own Implementation of Title"); 
    } 

    static void Main(string[] args) 
    { 
     ChildSubclass myChild = new ChildSubclass(); 
     myChild.DisplayTitle(); 
     Console.ReadLine(); 
    } 
    } 
} 

Я хотел бы получить ошибку компиляции, говоря, что «ChildSubClass» не может отменить «DisplayTitle». В настоящее время я получаю предупреждение - но похоже, что это то, что я должен был бы сделать, и я не знаю правильных атрибутов для маркировки метода.

ответ

10

Как я могу сделать это в C#. Я верю в Java, я бы просто отметил метод как «final», но я не могу найти альтернативы в C#.

Грубый эквивалент в C# sealed, но обычно это нужно только для виртуальных методов - и ваш метод DisplayTitle не является виртуальным.

Важно отметить, что ChildSubclassне перекрывая DisplayTitle - это скрывается его. Любой код, который использует ссылки только на Parent, не будет в конечном итоге вызвать эту реализацию.

Обратите внимание, что с кода как есть, вы должны получить предупреждение во время компиляции советую вам добавить модификатор new к методу в ChildSubclass:

public new void DisplayTitle() { ... } 

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

Ваш действительный здесь? Случайное злоупотребление или преднамеренные проблемы?

EDIT: Обратите внимание, что предупреждение для образца кода будет что-то вроде:

Test.cs(12,19): warning CS0108: 
     'ConsoleApplication1.ChildSubclass.DisplayTitle()' hides inherited 
     member 'ConsoleApplication1.Parent.DisplayTitle()'. Use the new keyword 
     if hiding was intended. 

Я предлагаю вам включить предупреждения в ошибки, а затем это труднее игнорировать их :)

+1

Я предполагаю, что моя настоящая забота будет случайным злоупотреблением. У меня есть абстрактный класс в другом проекте, который имеет метод TurnOn и TurnOff. Не вдаваясь в подробности - этот класс будет несколько подклассами, чтобы представлять объекты реального мира. Однако все эти устройства будут включены и выключены одинаково. Я просто не хочу, чтобы я или кто-то другой пытались реализовать свои собственные отключение/включение команд для отдельных устройств без предупреждения какого-либо типа. – user1720817

+0

@ user1720817: Хорошо было бы * быть * предупреждением. Я отредактирую предупреждение из вашего образца кода в свой ответ ... –

+0

Да, есть предупреждение :) Его просто мой OCD, который заставляет меня хотеть, чтобы это была ошибка времени компиляции. Спасибо, что нашли время, чтобы написать это! – user1720817

1

Используйте запечатанный модификатор, чтобы препятствовать переопределению классов, свойств или методов подклассами. Что не работает, когда вы используете печать?

http://msdn.microsoft.com/en-us/library/88c54tsw.aspx

+0

Когда я использую: «public sealed void DisplayTitle() {Console.WriteLine (« Title родителя »);}« Я получаю ошибку компиляции »« ConsoleApplication1.Parent.DisplayTitle() »не может быть запечатан, потому что это не переопределение ". – user1720817

2

Производный класс не может переопределить ваш метод, вы не объявили его virtual. Обратите внимание, что это очень отличается в C# по сравнению с Java, все методы являются виртуальными в Java. В C# вы должны явно использовать ключевое слово.

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

+0

+1, особенно для разницы в C#/Java. –

0

Я уверен, что то, что вы хотите, невозможно в C# с использованием ключевых слов-модификаторов метода.

Запечатанный применяется только при переопределении виртуального метода в классе предков, который затем предотвращает переопределение .

+0

Хорошая точка, но OP хочет предотвратить скрытие базового метода путем наследования классов. Это просто невозможно. –

+0

Я думаю, это похоже на то, что меня больше сбивает с толку - почему я могу запечатать метод, который унаследован, но не может сделать это в «базовом» классе? – user1720817

+0

@MichaelSallmen, я заявил, «что вы хотите, невозможно», где ваше замешательство? – Jace

Смежные вопросы