it-swarm.com.de

Was ist der Unterschied zwischen der expliziten oder impliziten Implementierung einer Schnittstelle?

In Visual Studio kann ich mit der rechten Maustaste auf eine Schnittstelle klicken und wählen, ob die Schnittstelle implementiert oder die Schnittstelle explizit implementiert werden soll.

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

Der einzige Unterschied, den ich zwischen den beiden sehe, besteht darin, dass der Schnittstellenname den Schnittstelleneigenschaften und -methoden beim Erstellen hinzugefügt wird, wenn Sie die Option "Schnittstelle explizit implementieren" auswählen.

Ich finde, dass der Code dadurch etwas lesbarer wird, da ich sehen kann, woher diese Methode/Eigenschaft stammt. Hat dies jedoch einen Unterschied in der Verwendung oder Kompilierung der Klasse? Und ist es wirklich wichtig, ob ich meine Schnittstellen implizit oder explizit implementiere?

67
Rachel

Check out die Top-Antwort von Andrew Barrett für "implizite vs. explizite Schnittstellenimplementierung" auf SO .

Grundsätzlich:

  • Implizit: Sie greifen auf die Schnittstellenmethoden und -eigenschaften zu, als wären sie Teil der Klasse.
  • Explizit: Sie können nur dann auf Methoden und Eigenschaften zugreifen, wenn Sie die Klasse als implementierte Schnittstelle behandeln.

Codebeispiele:

Implizit:

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

Explizit:

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

In Bezug auf "wann" müssen Sie eine Schnittstelle explizit implementieren, wenn Ihre Klasse bereits eine Methode mit derselben Signatur wie eine der Methoden Ihrer Schnittstelle hat oder wenn Ihre Klasse mehrere Schnittstellen implementiert, die Methoden mit denselben Signaturen gemeinsam nutzen aber inkompatible Verträge.

56
Jalayn

Es gibt auch einen Unterschied darin, wie Sie die Methode aufrufen.

Wenn Sie eine explizite Schnittstellenimplementierung verwenden, müssen Sie den Schnittstellentyp verwenden, um diese bestimmte Implementierung aufzurufen.

Beim Aufrufen von Code müssten Sie also eine Variable vom Typ ITest verwenden, um auf ITest.Id Zuzugreifen.

Der Artikel Explizite Schnittstellenimplementierung (C # -Programmierhandbuch) auf MSDN enthält ein gutes Beispiel.

8
Oded

Sie können zwei Schnittstellen implementieren, die dieselbe Methode definieren. Wenn Sie die Schnittstelle jedoch explizit implementieren, kann auf die Methoden nur zugegriffen werden, wenn die Variable in diese explizite Schnittstelle eingegeben wird.

Siehe: Explicit Interface Implementation Tutorial

4
unholysampler

BEARBEITEN: Es sollte keinen Unterschied machen Sie sollten es nicht tun es sei denn, Ihre Klasse implementiert zwei Schnittstellen mit denselben Eigenschaften, da Sie die entsprechende Schnittstelle umwandeln müssen, bevor Sie auf das Mitglied zugreifen können:

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

Die Beispielverwendung gilt, wenn Sie ein Schnittstellenmitglied explizit implementieren, auch wenn Sie nur eine einzige Schnittstelle verwenden (was ich immer vergesse: S). Daher würde ich versuchen, die explizite Implementierung nach Möglichkeit zu vermeiden, da dadurch Klassenmitglieder ausgeblendet werden, wenn sie ' werden nicht auf die richtige Oberfläche übertragen (was ziemlich verwirrend ist).

4
Ed James

Basierend auf Jalayans Antwort,

  • Implizit: Sie greifen auf die Schnittstellenmethoden und -eigenschaften zu, als wären sie Teil der Klasse.
  • Explizit: Sie können nur dann auf Methoden und Eigenschaften zugreifen, wenn Sie die Klasse als implementierte Schnittstelle behandeln.

(enter image description here