Por que a classe AC# pode herdar de uma interface implicitamente e explicitamente?
-
05-07-2019 - |
Pergunta
Hoje, acho que uma classe C# pode herdar uma interface de maneira implícita e explícita. Isso me surpreende. Se C# funcionar dessa maneira, uma instância poderá se comportar de maneira diferente quando referenciada de maneira diferente.
interface IFoo
{
void DoSomething();
}
class Foo : IFoo
{
#region IFoo Members
public void DoSomething()
{
Console.WriteLine("do something implicitly");
}
#endregion
#region IFoo Members
void IFoo.DoSomething()
{
Console.WriteLine("do something explicitly");
}
#endregion
}
Foo f = new Foo();
f.DoSomething();
((IFoo)f).DoSomething();
O código acima é executado e saída
do something implicitly
do something explicitly
Acredito que esse design de C# faça inconsistência do comportamento. Talvez seja obrigatório que uma classe C# possa herdar de uma interface de maneira implícita ou explicada, mas não ambos.
Existe alguma razão para que o C# seja projetado dessa maneira?
Solução
Seu exemplo faz não Implementar o IFOO implícita e explicitamente. Você implementa apenas o ifoo.Dosometing () explicitamente. Você tem um novo método em sua classe chamado Dosomething (). Não tem nada a ver com o ifoo.Dosoming, exceto que ele tem o mesmo nome e parâmetros.
Outras dicas
Cada classe que implementa uma interface tem um mapeamento entre os membros dessa classe e os membros da interface. Se a classe explicitamente implementa um membro da interface, então a implementação explícita irá sempre ser mapeado para a interface. Se não houver uma implementação explícita, é esperada uma implementação implícita e que será mapeada para a interface.
Quando uma classe tem o mesmo nome de membro e tipos associados como uma interface mas Também implementa explicitamente o membro correspondente para a interface, depois a implementação "implícita" da classe não é considerado uma implementação da interface de forma alguma (a menos que a implementação explícita a chama).
Além de significados diferentes em cada caso em que a classe implementa várias interfaces com o mesmo nome/tipo de membro, mesmo com apenas uma interface, o classe em si Considera -se ter uma interface implícita que pode ter o mesmo membro/tipos que a única interface, mas ainda significa algo diferente.
Isso o torna mais flexível para quando há colisões. Em particular, veja IEnumerator
e IEnumerator<T>
- Ambos têm um Current
propriedade, mas de diferentes tipos. Você tenho usar a implementação explícita da interface para implementar ambos (e o formulário genérico estende o formulário não genérico).
Heritância múltipla: e se você derivar de duas interfaces que definem o mesmo método para fins diferentes?
interface IMoveable
{
public void Act();
}
interface IRollable
{
public void Act();
}
class Thing : IMoveable, IRollable
{
//TODO Roll/Move code here
void IRollable.Act()
{
Roll();
}
void IMoveable.Act()
{
Move();
}
}
Gente, obrigado por suas respostas.
Acontece que "a classe C# pode herdar uma interface de maneira implícita e explícita ao mesmo tempo" é realmente uma ilusão. Na verdade, uma classe pode herdar uma interface por uma vez.
Na pergunta original, o método "doSomething" parece "implementar implicitamente" interface IFOO (o método é realmente gerado pelo VS2008), mas na verdade não é. Com a implementação explícita do IFOO da interface, o método "doSomething" gira apenas um método normal, que não tem nada a ver com o IFOO, exceto com a mesma assinatura.
Eu ainda acredito que é um design complicado de C#, e é fácil usá -lo erroneamente. Diga, eu tenho algum código como este
Foo f = new Foo();
f.DoSomething();
Agora, quero refatorá -lo abaixo do código. Parece perfeitamente bom, mas o resultado da execução é diferente.
Action<IFoo> func = foo => foo.DoSomething();
func(f);