Não, você não pode substituir um método não virtual. A coisa mais próxima que você pode fazer é ocultar o método criando um new
método com o mesmo nome, mas isso não é aconselhável, pois quebra os bons princípios de design.
Mas mesmo ocultar um método não dará a você o tempo de execução do despacho polimórfico de chamadas de método como uma verdadeira chamada de método virtual faria. Considere este exemplo:
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");
}
}
Neste exemplo, ambas as chamadas para o M
método print Foo.M
. Como você pode ver esta abordagem permitirá que você tenha uma nova implementação de um método, desde que a referência a esse objeto é do tipo derivado correto, mas escondendo um método base faz polimorfismo pausa.
Eu recomendo que você não oculte métodos básicos dessa maneira.
Eu tendo a ficar do lado daqueles que favorecem o comportamento padrão do C #, que os métodos são não virtuais por padrão (ao contrário do Java). Eu iria ainda mais longe e diria que as classes também deveriam ser fechadas por padrão. A herança é difícil de projetar adequadamente e o fato de haver um método que não está marcado como virtual indica que o autor desse método nunca pretendeu que o método fosse sobrescrito.
Editar: "envio polimórfico do tempo de execução" :
O que quero dizer com isso é o comportamento padrão que ocorre em tempo de execução quando você chama métodos virtuais. Digamos, por exemplo, que em meu exemplo de código anterior, em vez de definir um método não virtual, eu de fato defini um método virtual e um verdadeiro método substituído.
Se eu fosse chamar b.Foo
nesse caso, o CLR determinaria corretamente o tipo de objeto para o qual a b
referência aponta Bar
e despacharia a chamada M
apropriadamente.