Qual é a diferença entre implementar uma interface explícita ou implicitamente?


64

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

Captura de tela do Visual Studio

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ê optar por implementar a interface explicitamente.

Acho que torna o código um pouco mais legível, pois posso ver de onde vem esse método / propriedade. No entanto, isso faz alguma diferença na maneira como a classe é usada ou compilada? E realmente importa se eu implemento minhas interfaces de forma implícita ou explícita?

Respostas:


51

Confira a resposta principal de Andrew Barrett para "implementação implícita versus interface 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á possui um método com a mesma assinatura que um dos métodos da sua interface ou quando sua classe implementa várias interfaces que compartilham métodos com as mesmas assinaturas mas contratos incompatíveis.


11
Também achei a implementação explícita útil para ter uma espécie de interface "oculta" com operações inseguras. Também faz com que as chamadas para esses métodos se destaquem mais, o que é bom para coisas inseguras.
Tamás Szelei

Também vale mencionar que há um custo de desempenho no uso de interfaces explícitas, pois ele precisa colocar / desmarcar o objeto sempre que você referenciar a propriedade / método. Devido a isso, é melhor usar interfaces implícitas se possível
Rachel

3
@ Rachel: Pelo que sei, o custo de desempenho se aplica apenas aos tipos de valor.
Groky

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.

Portanto, ao chamar o código, você precisaria usar uma variável do tipo ITestpara acessar ITest.Id.

O artigo Implementação explícita da interface (Guia de Programação em C #) no MSDN tem um bom exemplo.



4

EDIT: Não deve fazer a diferença Você não deve fazê-lo, a menos que sua classe implemente duas interfaces com as mesmas propriedades, pois você precisará converter na interface relevante antes de poder 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 exemplo de uso é válido quando você implementa explicitamente um membro da interface, mesmo se você estiver usando apenas uma única interface (que eu sempre esqueço: S); portanto, tentaria evitar a implementação explícita sempre que possível, pois ocultará os membros da classe se eles ' não é transmitido para a interface correta (o que é bastante confuso).


3

Com base na resposta de Jalayan,

  • 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.

insira a descrição da imagem aqui

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.