Versioning with the Override and New Keywords (C# Programming Guide)

Destina-se a linguagem C# para que o controle de versão entre base e as classes derivadas bibliotecas diferentes podem evoluir e manter a compatibilidade com versões anteriores. Isso significa, por exemplo, que a introdução de um novo membro em uma base de classe com o mesmo nome como um membro em uma classe derivada é completamente suportado por C# e não resultar em comportamento inesperado. Isso também significa que uma classe deve declarar explicitamente se um método se destina a substituir um método herdado, ou se um método é um novo método que oculta um nome semelhante método herdado.

No C#, classes derivadas podem conter métodos com o mesmo nome que os métodos da classe base.

  • O método de classe base deve ser definido virtual.

  • Se o método na classe derivada não é precedido por nova ou Substituir palavras-chave, o compilador emitirá um aviso e o método se comportará como se o new palavra-chave estava presente.

  • Se o método na classe derivada é precedido de new palavra-chave, o método é definido como sendo independente do método em que a classe de base.

  • Se o método na classe derivada é precedido de override palavra-chave, objetos derivados da classe irá chamar o método em vez do método da classe base.

  • O método de classe base pode ser chamado de dentro da classe derivada usando o base palavra-chave.

  • O override, virtual, e new palavras-chave também podem ser aplicadas a propriedades, indexadores e eventos.

Por padrão, o C# métodos não são virtuais. Se um método é declarado como virtual, qualquer classe que herda o método pode implementar sua própria versão. Para tornar um método virtual, o virtual modificador é usado na declaração de método da classe de base. A classe derivada, em seguida, pode substituir o método virtual base usando o override palavra-chave ou ocultar o método virtual na classe base, usando o new palavra-chave. Se nem o override palavra-chave nem a new palavra-chave for especificado, o compilador emitirá um aviso e o método na classe derivada ocultará o método em que a classe de base.

Para demonstrar isso na prática, assumir por um momento que a empresa criou uma classe chamada GraphicsClass, que usa seu programa. Veja a seguir GraphicsClass:

class GraphicsClass
{
    public virtual void DrawLine() { }
    public virtual void DrawPoint() { }
}

Sua empresa usa essa classe, e você usá-lo para derivar sua própria classe, adicionando um novo método:

class YourDerivedGraphicsClass : GraphicsClass
{
    public void DrawRectangle() { }
}

Seu aplicativo é usado sem problemas, até que a empresa lança uma nova versão do GraphicsClass, que se parece com o seguinte código:

class GraphicsClass
{
    public virtual void DrawLine() { }
    public virtual void DrawPoint() { }
    public virtual void DrawRectangle() { }
}

A nova versão do GraphicsClass agora contém um método chamado DrawRectangle. Inicialmente, nada ocorre. A nova versão é ainda binário compatível com a versão antiga. Qualquer software que você implantou continue a funcionar, mesmo se a nova classe estiver instalada nesses sistemas de computador. As chamadas existentes para o método DrawRectangle continuará a referência a versão, em sua classe derivada.

No entanto, assim você recompilar seu aplicativo usando a nova versão do GraphicsClass, você receberá um aviso do compilador, CS0108. Este aviso informa que você deve considerar como você deseja que seu DrawRectangle método para se comportar de seu aplicativo.

Se você quiser que seu método para substituir o novo método de classe base, use o override palavra-chave:

class YourDerivedGraphicsClass : GraphicsClass
{
    public override void DrawRectangle() { }
}

O override palavra-chave certifica-se de que todos os objetos derivados de YourDerivedGraphicsClass usará a versão da classe derivada de DrawRectangle. Objetos derivados de YourDerivedGraphicsClass pode ainda acesso a versão da classe base DrawRectangle usando a palavra-chave base:

base.DrawRectangle();

Se você não quiser que seu método para substituir o novo método de classe base, as seguintes considerações se aplicam. Para evitar confusão entre os dois métodos, você pode renomear o seu método. Isso pode ser demorado e sujeito a erros e simplesmente não é prático em alguns casos. No entanto, se o projeto for relativamente pequeno, você pode usar opções Refactoring Visual Studio é para renomear o método. Para obter mais informações, consulte Refatoração de Classes e tipos (Designer de classe).

Como alternativa, você pode impedir que o aviso usando a palavra-chave new em sua definição de classe derivada:

class YourDerivedGraphicsClass : GraphicsClass
{
    public new void DrawRectangle() { }
}

Usando o new palavra-chave informa ao compilador que sua definição oculta a definição que está contida na classe de base. Esse é o comportamento padrão.

Substituição e método Selection

Quando um método é denominado em uma classe, o compilador C# seleciona o melhor método para chamar se mais de um método é compatível com a chamada, como quando não houver dois métodos com o mesmo nome, e parâmetros que são compatíveis com o parâmetro passado. Os métodos a seguir deve ser compatíveis:

public class Derived : Base
{
    public override void DoWork(int param) { }
    public void DoWork(double param) { }
}

Quando DoWork for chamado em uma instância do Derived, o compilador C# primeiro tenta tornar a chamada compatível com as versões do DoWork declarado originalmente no Derived. Métodos de substituição não são considerados como declarado em uma classe, eles são novas implementações de um método declarado em uma classe base. Somente se o compilador C# não pode corresponder a chamada método para um método original nele Derived tentará corresponder a chamada para um método substituído com o mesmo nome e parâmetros compatíveis. Por exemplo:

int val = 5;
Derived d = new Derived();
d.DoWork(val);  // Calls DoWork(double).

Porque a variável val pode ser convertida em um double implicitamente, o compilador C# chama DoWork(double) em vez de DoWork(int). Há duas maneiras para evitar isso. Primeiro, evite declarar novos métodos com o mesmo nome como métodos virtuais. Segundo, você pode instruir o compilador C# para chamar o método virtual tornando-localizar na lista método classe base por projetando a instância do Derived para Base. Porque o método é virtual, a implementação de DoWork(int) em Derived será chamada. Por exemplo:

((Base)d).DoWork(val);  // Calls DoWork(int) on Derived.

Consulte também

Referência

Classes e estruturas (guia de programação de C#)

Methods (C# Programming Guide)

Inheritance (C# Programming Guide)

Conceitos

C# Programming Guide