Qual é a diferença entre implementar uma interface de forma explícita ou implícita?

42

No Visual Studio, posso clicar com o botão direito do mouse em uma interface e escolher Implementar Interface ou Implementar Interface Explicitamente.

public class Test : ITest
{
    public string Id // Generated by Implement Interface
    {
        get { throw new NotImplementedException(); }
    }

    string ITest.Id // Generated by Implement Interface Explicitly
    {
        get { throw new NotImplementedException(); }
    }
}

A única diferença que vejo entre os dois é que o nome da Interface é adicionado às propriedades e métodos da interface quando eles são criados, se você escolher Implementar Interface Explicitamente.

Acho que isso torna o código um pouco mais legível, já que posso ver de onde vem esse método / propriedade, mas isso faz alguma diferença em como a classe é usada ou compilada? E isso realmente importa se eu implementar minhas interfaces implícita ou explicitamente?

    
por Rachel 22.02.2012 / 15:29
fonte

4 respostas

35

Confira a principal resposta de Andrew Barrett para " implementação da interface implícita versus explícita "no SO .

Basicamente:

  • Implícito: você acessa os métodos e propriedades da interface como se fossem parte da classe.
  • Explícito: você só pode acessar métodos e propriedades ao tratar a classe como a interface implementada.

Exemplos de código:

Implícito:

Test t = new Test();
t.Id; // OK
((ITest)t).Id; // OK

Explícito:

Test t = new Test();
t.Id; // Not OK
((ITest)t).Id; // OK

Em termos de "quando" você precisa implementar uma interface explicitamente, é quando sua classe já tem um método com a mesma assinatura de um dos métodos da sua interface, ou quando sua classe implementa várias interfaces que compartilham métodos com as mesmas assinaturas.

    
por 22.02.2012 / 15:36
fonte
8

Há também uma diferença em como você chama o método.

Ao usar uma implementação de interface explícita , você deve usar o tipo de interface para chamar essa implementação específica.

Assim, no código de chamada, você precisaria usar uma variável do tipo ITest para acessar ITest.Id .

O artigo Implementação explícita da interface (guia de programação C #) no MSDN é um bom exemplo.

    
por 22.02.2012 / 15:34
fonte
3

Ele permite que você implemente duas interfaces que definem o mesmo método. No entanto, se você implementar explicitamente a interface, os métodos só poderão ser acessados quando a variável for digitada nessa interface explícita.

Veja: Tutorial explícito de implementação da interface

    
por 22.02.2012 / 15:35
fonte
3

EDITAR: Ele não deve fazer diferença Você não deve fazer isso a menos que sua classe implemente duas interfaces com as mesmas propriedades, pois você terá que converter para a interface relevante antes você pode acessar o membro:

public interface ITest
{
    string Id { get; }
}

public interface IAlsoTest
{
    string Id { get; }
}

public interface ITestToo
{
    int Id { get; }
}

public class Test : ITest, IAlsoTest
{
    // Valid implicit implementation of BOTH interfaces
    public string Id
    {
        get { throw new NotImplementedException(); }
    }
}

public class TestSeparately : ITest, ITestToo
{
    // This way we can do different things depending
    // on which interface the callee called from.
    string ITest.Id
    {
        get { throw new NotImplementedException(); }
    }

    int ITestToo.Id
    {
        get { throw new NotImplementedException(); }
    }
}

public class TestOuch
{
    public void DoStuff()
    {
        var ts = new TestSeparately();

        // Works
        Console.WriteLine(((ITest)ts).Id);

        // Works
        Console.WriteLine(((ITestToo)ts).Id);

        // Not valid! Which one did we want to call?
        Console.WriteLine(ts.Id);
    }
}

O uso de exemplo é válido quando você implementa explicitamente um membro de interface mesmo se você estiver usando apenas uma única interface (que eu sempre esqueço: S), então tentaria evitar a implementação explícita sempre que possível, pois isso ocultaria os membros da classe. se eles não forem lançados na interface correta (o que é bastante confuso).

    
por 22.02.2012 / 15:38
fonte

Tags