A interface não virtual (NVI) é útil como útil em C# como em C ++?
-
22-09-2019 - |
Pergunta
Em C ++, muitas vezes precisava Nvi Para obter consistência nas minhas APIs. Não vejo isso usado tanto entre outros em C#, no entanto. Gostaria de saber se é porque C#, como um idioma, oferece recursos que tornam o NVI desnecessário? (Ainda uso o NVI em C#, onde necessário.)
Solução
Eu acho que a explicação é simplesmente que, em C#, o OOP "tradicional" do estilo Java é muito mais arraigado, e o NVI é controlado por isso. C# tem um verdadeiro interface
Tipo, enquanto o NVI conta com a "interface" sendo uma classe base. De qualquer maneira, é assim que é feito em C ++, então se encaixa naturalmente lá.
No C#, ainda pode ser feito e ainda é um idioma muito útil (muito mais, eu diria que as interfaces "normais"), mas exige que você ignore um recurso de linguagem interno.
Muitos programadores C# simplesmente não pensavam em uma classe NVI como "uma interface adequada". Eu acho que essa resistência mental é a única razão pela qual é menos comum em C#.
Outras dicas
C# apresenta um problema com o NVIS, retirando a herança múltipla. Embora eu pense que a herança múltipla gera mais má do que o bem, é necessário (na maioria dos casos) para o NVI. A coisa mais simples que se lembra: uma classe em C# não pode implementar mais de um NVI. Uma vez que se descobre este desagradável aspecto de C#/nVI tandem, fica muito mais fácil desistir do NVIS do que C#.
E a propósito, falando sobre aspectos. Esse é um conceito muito interessante, e seu objetivo é exatamente o mesmo que o da NVIS, só que tenta olhar para o "verdadeiro essense" da questão e abordá -lo "corretamente", por assim dizer. Dê uma olhada.
E, no que diz respeito à estrutura .NET, existe um mecanismo para fazer exatamente isso: injetar código que é "ortogonal", por assim dizer, para a lógica principal em questão. Estou falando de todo esse negócio de Marshalbyref/TransparentProxy, tenho certeza que você já ouviu falar disso. No entanto, isso afeta seriamente o desempenho, então não há grande sorte aqui.
Também houve inúmeras tentativas de implementar o mesmo conceito por meio de outras técnicas, desde a construção de fachadas até os negócios sujos mencionados acima até o pós-processamento do MSIL.
A última abordagem passa a atrair a sua de verdade, pois pode ser tornada transparente (incorporando as etapas necessárias na rotina de construção de alguém), não afeta o desempenho (mais do que é absolutamente necessário para realmente executar o código "ortogonal") E não envolve algum tipo de "hacking" ou engenharia reversa, já que o MSIL está aberto e bem documentado.
Aqui Pode -se encontrar esses pontos discutidos com mais detalhes, além de mais informações e links para ferramentas reais. Usar o Google para o mesmo objetivo também é aceitável. :-)
Boa sorte.
Trey Nash em seu livro Acelerado C# promove o padrão NVI como uma forma canônica em C#.
Não sei quem escreveu o artigo que você faz referência (Mais idiomas C ++/interface não virtual), mas sinto que o autor perdeu o ponto.
...
Interface versus classes abstratas
Eu argumentaria que, filosoficamente, há pouca diferença (em C#) entre uma classe totalmente abstrata (ou seja, nenhuma implementação) versus uma interface. Na superfície, ambos podem fornecer uma assinatura de métodos que podem ser executados e exigem outra coisa para implementar essa funcionalidade.
Com C#, você sempre programaria para uma interface se o que você precisa for uma interface. Você usa apenas uma classe base (resumo) porque também deseja reutilização de implementação.
Muitas bases de código combinam essas e programam a interface, além de fornecer uma hierarquia de classes como uma implementação padrão para a interface.
NVI para interfaces em C
Se sua única motivação para usar o NVI no C ++ seria ter uma interface, não, você não usará isso em C# porque o idioma / CLR fornece interfaces como um recurso de primeira classe.
NVI e hierarquias de objetos
Na minha opinião, o NVI nunca foi sobre interfaces. Sempre foi uma excelente maneira de implementar o Método do modelo padronizar.
A utilidade se manifesta na manutenção do ciclo de vida do código (facilidade de mudança, extensão etc.) e fornece um modelo mais simples de herança.
Minha opinião: sim, o NVI é muito útil em C#.
Eu acho que o NVI é tão útil em C# quanto em C ++. Vejo que é usado com muita frequência na minha empresa.