Durante um dos meus estudos sobre os meandros do C #, deparei-me com uma passagem interessante sobre a implementação explícita da interface.
While this syntax is quite helpful when you need to resolve name clashes,
you can use explicit interface implementation simply to hide more "advanced"
members from the object level.
A diferença entre permitir o uso object.method()
ou exigir o lançamento de algo ((Interface)object).method()
parece uma ofuscação mesquinha para meus olhos inexperientes. O texto observou que este irá esconder o método de Intellisense no nível do objeto, mas por que você iria querer fazer isso se não fosse necessário para evitar conflitos de nome?
c#
design
interfaces
Nathanus
fonte
fonte
Respostas:
Imagine uma situação em que uma interface força uma classe a implementar métodos que, na verdade, não fazem sentido como parte da classe. Isso geralmente pode acontecer quando as interfaces são particularmente grandes e violam o Princípio de Segregação de Interface.
Essa classe precisa implementar a interface, mas em vez de poluir sua interface pública altamente visível com métodos que não fazem sentido, você pode implementar explicitamente os métodos que você não deseja que estejam obviamente disponíveis. A interface pública altamente visível da classe é como você deseja que a classe seja usada e a implementação explícita existe quando a classe é acessada através da interface.
fonte
IEnumerable<T>
que se comporte como a concatenação de duas outras. SeIEnumerable<T>
incluísse uma propriedade para dizer se sua contagem era conhecida, potencialmente infinita ou nenhuma, juntamente com um método para perguntar qual era sua contagem, uma classe que agrega váriosIEnumerable<T>
e se comporta como uma concatenação poderia relatar sua contagem de maneira eficiente no caso de alguns as coleções encapsuladas conheciam suas contagens.A aplicação mais útil que encontrei é na implementação de fábricas. Em muitos casos, é útil criar classes mutáveis dentro da fábrica, mas imutáveis para classes externas. Isso pode ser facilmente implementado em Java usando classes internas, tornando os campos e seus setters privados e apenas expondo os getters como membros públicos. No entanto, em C #, eu tive que usar interfaces explícitas para conseguir a mesma coisa. Vou explicar melhor:
Em Java, a classe interna AND e a classe externa podem acessar membros privados um do outro, o que faz total sentido, pois as classes estão intimamente relacionadas. Eles estão no mesmo arquivo de código e provavelmente são desenvolvidos pelo mesmo desenvolvedor. Isso significa que os campos e métodos privados da classe interna ainda podem ser acessados pela fábrica para modificar seus valores. Mas as classes externas não poderão acessar esses campos, exceto por meio de getters públicos.
No entanto, em C #, as classes externas não podem acessar membros particulares de classes internas, para que o conceito não seja diretamente aplicável. Eu usei uma interface explícita como solução alternativa, definindo uma interface privada na classe externa e implementando-a explicitamente na classe interna. Dessa forma, somente a classe externa pode acessar os métodos nessa interface da mesma maneira que é feita em Java (mas eles devem ser métodos, não campos).
Exemplo:
É para isso que eu usaria interfaces explícitas.
fonte
Se uma classe implementar duas interfaces que contêm um membro com a mesma assinatura, a implementação desse membro na classe fará com que ambas as interfaces usem esse membro como sua implementação. No exemplo a seguir, todas as chamadas para
Paint
invocar o mesmo método. C #Por outro lado, a implementação explícita de um (ou de ambos) permite especificar um comportamento diferente para cada um.
fonte
Interfaces explícitas são úteis quando um objeto possui duas ou mais formas muito distintas de comunicação.
Por exemplo, um objeto que mantém uma coleção de objetos filho que precisam se comunicar com o pai.
Existem algumas ações que queremos apenas acessíveis a chamadores externos e outras que queremos apenas acessíveis aos objetos filho.
Interfaces explícitas ajudam a garantir essa divisão.
fonte
Talvez se você tivesse uma funcionalidade que fosse útil para os usuários, mas apenas se você realmente souber o que está fazendo (o suficiente para ler a documentação para aprender sobre a função), mas que provavelmente quebrará as coisas se não o fizer.
Por que você faria isso em vez de fornecer, diga uma segunda "interface de recursos avançados" que eu não conheço.
fonte
Geralmente, o código é lido mais do que está escrito e eu só uso o Intellisense para escrever código rapidamente. Eu não escreveria código de uma maneira específica apenas para tornar o Intellisense mais agradável.
Eu particularmente não vejo como
((Interface) objeto) .method () é mais legível que object.method ().
Se eu tivesse muitos métodos em um objeto específico, eu poderia questionar se é um objeto deus ou não e, na verdade, deveria ser dividido em vários objetos mais simples.
fonte