Eu e um colega de trabalho estávamos analisando o comportamento da new
palavra - chave em C #, conforme ela se aplica ao conceito de ocultação. A partir da documentação :
Use o novo modificador para ocultar explicitamente um membro herdado de uma classe base. Para ocultar um membro herdado, declare-o na classe derivada usando o mesmo nome e modifique-o com o novo modificador.
Lemos a documentação e entendemos o que basicamente faz e como faz. O que realmente não conseguimos entender é por que você precisaria fazê-lo em primeiro lugar. O modificador existe desde 2003, e nós dois trabalhamos com o .Net por mais tempo do que isso e nunca foi lançado.
Quando esse comportamento seria necessário no sentido prático (por exemplo, quando aplicado a um caso de negócios)? Esse é um recurso que sobreviveu à sua utilidade ou é simplesmente incomum o suficiente no que fazemos (especificamente fazemos formulários da Web e aplicativos MVC e alguns pequenos fatores WinForms e WPF)? Ao experimentar esta palavra-chave e brincar com ela, encontramos alguns comportamentos que ela permite que pareçam um pouco perigosos se mal utilizados.
Isso parece um pouco aberto, mas estamos procurando um caso de uso específico que possa ser aplicado a um aplicativo de negócios que considere útil essa ferramenta específica.
Respostas:
Você pode usá-lo para imitar a covariância do tipo de retorno. Explicação de Eric Lippert . Eric fornece este exemplo de código:
Esta é uma solução alternativa.
public override Fish Contents() { ... }
não é legal, apesar de ser seguro.Em geral, você não deve usar ocultação de método, pois isso é confuso para os consumidores da sua classe (o exemplo específico acima não sofre com esse problema). Apenas dê outro nome ao seu novo método, se você não quiser substituir um método existente.
Uma situação provável no mundo real em que você precisaria ocultar o método é se o provedor de uma classe base adicionou um método genérico que você já havia adicionado a uma classe derivada. Esse programa compila (e avisa) sem a nova palavra-chave, mas a adição
new
diz: "Eu sei que minha versão deste método está substituindo a versão da classe base. Isso é horrível e confuso, mas estamos presos a ela". Isso ainda é melhor do que forçar a classe derivada a renomear seu método.Apenas permitir que o método derivado seja tratado como uma substituição causaria problemas. Ignorando quaisquer preocupações com a implementação do compilador, o novo método é semanticamente diferente do método base, mas o polimorfismo faria com que o novo método fosse chamado quando solicitado a chamar um método com o mesmo nome.
Essa situação é discutida em detalhes neste post por Eric Lippert.
fonte
new
ser um marcador de "isso é horrível e confuso".Acho que existe, caso você precise fazer algo que os designers de linguagem talvez não tenham pensado. O C # foi de várias maneiras uma reação às versões anteriores do java. E uma coisa que o java fez foi explicitar os desenvolvedores de maneira explícita para eliminar as possibilidades de desenvolvedores se atirarem nos pés. O C # adotou uma abordagem um pouco diferente e deu aos desenvolvedores um pouco mais de poder para permitir que os desenvolvedores tivessem mais oportunidades de se atirar nos pés. Um exemplo é a
unsafe
palavra - chave Estanew
palavra-chave é outra.Agora, provavelmente não é tão útil quanto,
unsafe
mas quando você entra em uma especificação de idioma, é difícil sair de uma especificação de idioma.fonte
Está dizendo ao leitor que "ocultei deliberadamente a implementação desse método pela classe base", em vez de acidentalmente.
fonte
Você pode querer disponibilizar o membro anterior por outro nome:
Felicidades.
fonte
Eu achei bastante útil ao criar um conjunto de testes para código legado. Ele me permite ocultar dependências externas, como consultar um banco de dados dentro de um método usado por outros métodos. Para poder testar os outros métodos, posso ocultar a lógica original que depende de recursos externos sem precisar adicionar a palavra-chave virtual a esses métodos nas classes de teste.
fonte