Explizite Schnittstellenimplementierung (C#-Programmierhandbuch)

Wenn eine Klasse zwei Schnittstellen implementiert, die einen Member mit derselben Signatur enthalten, bewirkt die Implementierung dieses Members in der Klasse, dass beide Schnittstellen diesen Member als ihre Implementierung verwenden. Im folgenden Beispiel rufen alle Aufrufe von Paint dieselbe Methode auf. In diesem ersten Beispiel werden die Typen definiert:

public interface IControl
{
    void Paint();
}
public interface ISurface
{
    void Paint();
}
public class SampleClass : IControl, ISurface
{
    // Both ISurface.Paint and IControl.Paint call this method.
    public void Paint()
    {
        Console.WriteLine("Paint method in SampleClass");
    }
}

Im folgenden Beispiel werden die Methoden aufgerufen:

SampleClass sample = new SampleClass();
IControl control = sample;
ISurface surface = sample;

// The following lines all call the same method.
sample.Paint();
control.Paint();
surface.Paint();

// Output:
// Paint method in SampleClass
// Paint method in SampleClass
// Paint method in SampleClass

Aber Sie möchten vielleicht nicht, dass für beide Schnittstellen die gleiche Implementierung aufgerufen wird. Um eine andere Implementierung aufzurufen, je nachdem welche Schnittstelle verwendet wird, können Sie einen Schnittstellenmember explizit implementieren. Eine explizite Schnittstellenimplementierung ist ein Klassenmember, der nur über die angegebene Schnittstelle aufgerufen wird. Benennen Sie den Klassenmember, indem Sie ihm den Namen der Schnittstelle und einen Punkt voranstellen. Zum Beispiel:

public class SampleClass : IControl, ISurface
{
    void IControl.Paint()
    {
        System.Console.WriteLine("IControl.Paint");
    }
    void ISurface.Paint()
    {
        System.Console.WriteLine("ISurface.Paint");
    }
}

Der Klassenmember IControl.Paint ist nur über die Schnittstelle IControl verfügbar, und ISurface.Paint ist nur über ISurface verfügbar. Beide Methodenimplementierungen sind voneinander getrennt, und sie sind nicht direkt in der Klasse verfügbar. Zum Beispiel:

SampleClass sample = new SampleClass();
IControl control = sample;
ISurface surface = sample;

// The following lines all call the same method.
//sample.Paint(); // Compiler error.
control.Paint();  // Calls IControl.Paint on SampleClass.
surface.Paint();  // Calls ISurface.Paint on SampleClass.

// Output:
// IControl.Paint
// ISurface.Paint

Die explizite Implementierung wird auch zum Lösen von Konflikten verwendet, bei denen zwei Schnittstellen verschiedene Member mit demselben Namen deklarieren, z. B. eine Eigenschaft und eine Methode. Zum Implementieren beider Schnittstellen muss eine Klasse die explizite Implementierung für die Eigenschaft P, die Methode P oder beide verwenden, um einen Compilerfehler zu vermeiden. Zum Beispiel:

interface ILeft
{
    int P { get;}
}
interface IRight
{
    int P();
}

class Middle : ILeft, IRight
{
    public int P() { return 0; }
    int ILeft.P { get { return 0; } }
}

Eine explizite Schnittstellenimplementierung besitzt keinen Zugriffsmodifizierer, da auf sie nicht als Member des Typs zugegriffen werden kann, in dem sie definiert ist. Sie ist nur verfügbar, wenn sie über eine Instanz der Schnittstelle aufgerufen wird. Wenn Sie einen Zugriffsmodifizierer für eine explizite Schnittstellenimplementierung angeben, erhalten Sie den Compilerfehler CS0106. Weitere Informationen finden Sie unter interface (C#-Referenz).

Sie können eine Implementierung für in einer Schnittstelle deklarierte Member definieren. Wenn eine Klasse eine Methodenimplementierung von einer Schnittstelle erbt, ist diese Methode nur über einen Verweis des Schnittstellentyps zugänglich. Der geerbte Member wird nicht als Teil der öffentlichen Schnittstelle angezeigt. Im folgenden Beispiel wird eine Standardimplementierung für eine Schnittstellenmethode definiert:

public interface IControl
{
    void Paint() => Console.WriteLine("Default Paint method");
}
public class SampleClass : IControl
{
    // Paint() is inherited from IControl.
}

Im folgenden Beispiel wird die Standardimplementierung aufgerufen:

var sample = new SampleClass();
//sample.Paint();// "Paint" isn't accessible.
var control = sample as IControl;
control.Paint();

Alle Klassen, die die IControl-Schnittstelle implementieren, können die Standardmethode Paint überschreiben: entweder als öffentliche Methode oder als explizite Schnittstellenimplementierung.

Weitere Informationen