Как запретить переопределение метода / свойства класса в C #? - PullRequest
8 голосов
/ 05 июля 2011

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

Ответы [ 5 ]

14 голосов
/ 05 июля 2011

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

Они могут быть затенены в производных классах, по общему признанию:

public new void SomeMethod()
{
}

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

Если бы вы могли дать нам более подробную информацию о точно , что вы пытаетесь предотвратить (как от POV вызывающего абонента, так и от вызываемого кода), мы могли бы помочь больше.

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

Метод, который еще не является переопределением, не будет переопределен, если вы не отметите его как virtual.Похоже, в вашем случае никаких действий не требуется.

class A
{
    public void B() {} // can't override
    public virtual C() {} // can override
    public virtual D() {} // can override
}

Модификатор sealed применяется только тогда, когда метод является уже переопределением члена в базовом классе.Это позволяет предотвратить переопределения в подклассах класса , .

class A1 : A
{
    public void B() {} // shadows A.B.  Not a virtual method!
    public override C() {} // overrides A.C, subclasses can override
    public override sealed D() {} // overrides A.D, subclasses cannot override
                                  // (but can shadow)
}
2 голосов
/ 05 июля 2011

Это невозможно. Производный класс всегда может использовать ключевое слово new для hide (не переопределять) своих родительских методов. Ключевое слово sealed просто запрещает производному классу переопределять виртуальный метод, но оно все равно может использовать new, чтобы скрыть базовый метод.

1 голос
/ 05 июля 2011

Ключевое слово «sealed» можно использовать только в том случае, если вы переопределяете виртуальный метод, но не хотите, чтобы класс, производный от вашей реализации, переопределял его снова.Все, что вам нужно - объявить метод не виртуальным.

Как уже отмечалось, на самом деле существует ключевое слово "new", которое позволяет скрыть метод.Но до тех пор, пока вы используете ссылку на ваш базовый класс, ваш базовый метод всегда вызывается:

class BaseClass
{
     public void Foo() { Console.WriteLine("Foo"); }
}

class Derived : BaseClass
{
     public new void Foo() { Console.WriteLine("Bar"); }
}

public static void Main()
{
     Derived derived = new Derived();
     derived.Foo(); // Prints "Bar"
     BaseClass baseClass = derived;
     baseClass.Foo(); // Prints "Foo"
}

Поскольку предоставление базового класса имеет смысл, только если вы используете указатель «BaseClass»везде ваш метод не может быть скрыт.

0 голосов
/ 05 июля 2011

Это именно то, для чего используется ключевое слово sealed.

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

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

Если вы переопределили метод из базового класса, тогда используйте sealed. Если вы объявили метод в классе и не хотите, чтобы он был переопределен в каких-либо производных классах, тогда не помечайте как virtual. Только virtual члены могут быть переопределены.

...