Freigeben über


Explizite Schnittstellenimplementierung (C#-Programmierhandbuch)

Wenn eine Klasse zwei Schnittstellen implementiert, die ein Element mit derselben Signatur enthalten, führt die Implementierung dieses Elements in der Klasse dazu, dass beide Schnittstellen dieses Element als Implementierung verwenden. Im folgenden Beispiel werden alle Aufrufe zum Paint Aufrufen derselben Methode ausgeführt. 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

Möglicherweise möchten Sie jedoch nicht, dass die gleiche Implementierung für beide Schnittstellen aufgerufen wird. Zum Aufrufen einer anderen Implementierung, je nachdem, welche Schnittstelle verwendet wird, können Sie ein Schnittstellenelement explizit implementieren. Eine explizite Schnittstellenimplementierung ist ein Klassenmemmemm, der nur über die angegebene Schnittstelle aufgerufen wird. Benennen Sie das Klassenelement, indem Sie es dem Namen der Schnittstelle und einem Punkt voranstellen. Beispiel:

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

Der Klassenmemmemm IControl.Paint ist nur über die IControl Schnittstelle verfügbar und ISurface.Paint nur über ISurface. Beide Methodenimplementierungen sind voneinander getrennt und stehen auch nicht direkt auf der Klasse zur Verfügung. 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 verwendet, um Fälle aufzulösen, in denen zwei Schnittstellen jeweils unterschiedliche Member desselben Namens deklarieren, z. B. eine Eigenschaft und eine Methode. Um beide Schnittstellen zu implementieren, muss eine Klasse explizite Implementierung entweder für die Eigenschaft Poder die Methode Poder beides verwenden, um einen Compilerfehler zu vermeiden. 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 verfügt nicht über einen Zugriffsmodifizierer, da er nicht als Mitglied des Typs zugegriffen werden kann, in dem er definiert ist. Stattdessen kann nur über eine Instanz der Schnittstelle aufgerufen werden. 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 Elemente definieren, die in einer Schnittstelle deklariert sind. Wenn eine Klasse eine Methodenimplementierung von einer Schnittstelle erbt, kann auf diese Methode nur über einen Verweis des Schnittstellentyps zugegriffen werden. Das geerbte Element 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();

Jede Klasse, die die IControl Schnittstelle implementiert, kann die Standardmethode Paint außer Kraft setzen, entweder als öffentliche Methode oder als explizite Schnittstellenimplementierung.

Siehe auch