Nie, nie możesz zastąpić metody niewirtualnej. Najbliższą rzeczą, jaką możesz zrobić, jest ukrycie metody, tworząc new
metodę o tej samej nazwie, ale nie jest to zalecane, ponieważ łamie dobre zasady projektowania.
Ale nawet ukrycie metody nie zapewni polimorficznego wysyłania wywołań metod w czasie wykonywania, jak w przypadku prawdziwego wywołania metody wirtualnej. Rozważmy ten przykład:
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");
}
}
W tym przykładzie oba wywołania M
metody print Foo.M
. Jak widać to podejście nie pozwala mieć nową implementację metody tak długo jak odniesienie do tego obiektu jest z odpowiedniego typu pochodzącego ale ukrywa metodę bazowy ma polimorfizm przerwy.
Zalecałbym, abyś nie ukrywał w ten sposób podstawowych metod.
Zwykle jestem po stronie tych, którzy preferują domyślne zachowanie C #, polegające na tym, że metody są domyślnie niewirtualne (w przeciwieństwie do Javy). Poszedłbym jeszcze dalej i powiedziałbym, że klasy powinny być również domyślnie zapieczętowane. Dziedziczenie jest trudne do prawidłowego zaprojektowania, a fakt, że istnieje metoda, która nie jest oznaczona jako wirtualna, wskazuje, że autor tej metody nigdy nie zamierzał nadpisywać metody.
Edycja: "wysyłka polimorficzna czasu wykonania" :
Rozumiem przez to domyślne zachowanie, które ma miejsce w czasie wykonywania, gdy wywołujesz metody wirtualne. Powiedzmy na przykład, że w moim poprzednim przykładzie kodu, zamiast definiować metodę niewirtualną, w rzeczywistości zdefiniowałem metodę wirtualną, a także metodę true overridden.
Gdybym miał wywołać b.Foo
w takim przypadku, CLR poprawnie określiłby typ obiektu, na który b
wskazuje odwołanie, Bar
i odpowiednio wysłałby wywołanie M
.