web-dev-qa-db-fra.com

Quelle est la différence entre implémenter une interface explicitement ou implicitement?

Dans Visual Studio, je peux cliquer avec le bouton droit sur une interface et choisir d'implémenter l'interface ou d'implémenter l'interface de manière explicite.

Visual Studio Screenshot

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(); }
    }
}

La seule différence que je vois entre les deux est que le nom de l'interface est ajouté aux propriétés et méthodes de l'interface lors de leur création si vous choisissez d'implémenter l'interface de manière explicite.

Je trouve que cela rend le code un peu plus lisible car je peux voir d'où vient cette méthode/propriété, mais cela fait-il une différence dans la façon dont la classe est utilisée ou compilée? Et est-ce vraiment important si j'implémente mes interfaces implicitement ou explicitement?

67
Rachel

Consultez la meilleure réponse d'Andrew Barrett pour "implémentation implicite vs explicite d'interface" sur SO .

Fondamentalement:

  • Implicite: vous accédez aux méthodes et propriétés d'interface comme si elles faisaient partie de la classe.
  • Explicite: vous ne pouvez accéder aux méthodes et propriétés qu'en traitant la classe comme l'interface implémentée.

Exemples de code:

Implicite:

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

Explicite:

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

En termes de "quand" vous devez implémenter une interface explicitement, c'est quand votre classe a déjà une méthode avec la même signature que l'une des méthodes de votre interface, ou quand votre classe implémente plusieurs interfaces qui partagent des méthodes avec les mêmes signatures mais des contrats incompatibles.

56
Jalayn

Il existe également une différence dans la façon dont vous appelez la méthode.

Lorsque vous utilisez une implémentation d'interface explicite , vous devez utiliser le type d'interface pour appeler cette implémentation spécifique.

Ainsi, lors de l'appel de code, vous devrez utiliser une variable de type ITest pour accéder à ITest.Id.

L'article Mise en œuvre d'interface explicite (Guide de programmation C #) sur MSDN en est un bon exemple.

8
Oded

Il vous permet d'implémenter deux interfaces qui définissent la même méthode. Cependant, si vous implémentez explicitement l'interface, les méthodes ne sont accessibles que lorsque la variable est saisie dans cette interface explicite.

Voir: Tutoriel d'implémentation d'interface explicite

4
unholysampler

ÉDITER: Cela ne devrait pas faire de différence Vous ne devriez pas le faire sauf si votre classe implémente deux interfaces avec les mêmes propriétés, car vous devrez transtyper vers l'interface appropriée avant de pouvoir accéder au membre:

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);
    }
}

L'exemple d'utilisation s'applique lorsque vous implémentez explicitement un membre d'interface même si vous n'utilisez qu'une seule interface (que j'oublie toujours: S), donc j'essayerais d'éviter l'implémentation explicite chaque fois que possible, car cela masquera les membres de la classe s'ils ' re pas jeté sur la bonne interface (ce qui est assez déroutant).

4
Ed James

Sur la base de la réponse de Jalayan,

  • Implicite: vous accédez aux méthodes et propriétés d'interface comme si elles faisaient partie de la classe.
  • Explicite: vous ne pouvez accéder aux méthodes et propriétés qu'en traitant la classe comme l'interface implémentée.

enter image description here

4