Ні, ви не можете замінити невіртуальний метод. Найближче, що ви можете зробити, це приховати метод, створивши new
метод з такою ж назвою, але це не доцільно, оскільки це порушує хороші принципи проектування.
Але навіть приховування методу не дасть вам часу виконання поліморфного відправлення викликів методів, як справжній виклик віртуального методу. Розглянемо цей приклад:
using System;
class Example
{
static void Main()
{
Foo f = new Foo();
f.M();
Foo b = new Bar();
b.M();
}
}
class Foo
{
public void M()
{
Console.WriteLine("Foo.M");
}
}
class Bar : Foo
{
public new void M()
{
Console.WriteLine("Bar.M");
}
}
У цьому прикладі обидва виклики M
методу print Foo.M
. Як ви можете бачити , цей підхід дійсно дозволяє мати нову реалізацію методу до тих пір , як посилання на цей об'єкт має правильний похідний тип , але приховує базовий метод робить перерву поліморфізм.
Я б рекомендував вам не приховувати базові методи таким чином.
Я схильний дотримуватися тих, хто віддає перевагу поведінці за замовчуванням C #, згідно з якою методи за замовчуванням невіртуальні (на відміну від Java). Я пішов би ще далі і сказав, що класи також повинні бути запечатані за замовчуванням. Спадщину важко розробити належним чином, і той факт, що існує метод, який не позначений як віртуальний, вказує на те, що автор цього методу ніколи не передбачав, щоб метод був замінений.
Змінити: "час виконання поліморфного відправлення" :
Я маю на увазі це поведінку за замовчуванням, яка трапляється під час виконання під час виклику віртуальних методів. Скажімо, наприклад, що в моєму попередньому прикладі коду, замість того, щоб визначати невіртуальний метод, я фактично також визначив віртуальний метод і справжній перевизначений метод.
Якби я зателефонував b.Foo
у такому випадку, CLR правильно визначив би тип об’єкта, на який b
вказує посилання, Bar
і надсилав би виклик M
належним чином.