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?

Foi útil?

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);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top