次の方法で共有


明示的なインターフェイスの実装 (C# プログラミング ガイド)

クラスが同じシグネチャを持つメンバーを含む 2 つのインターフェイスを実装する場合、そのメンバーをクラスに実装すると、両方のインターフェイスがそのメンバーを実装として使用することになります。 次の例では、 Paint のすべての呼び出しで同じメソッドが呼び出されます。 この最初のサンプルでは、型を定義します。

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

次の例では、メソッドを呼び出します。

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

ただし、両方のインターフェイスに対して同じ実装を呼び出したくない場合があります。 使用中のインターフェイスに応じて異なる実装を呼び出すには、インターフェイス メンバーを明示的に実装できます。 明示的なインターフェイス実装は、指定されたインターフェイスを介してのみ呼び出されるクラス メンバーです。 インターフェイスの名前とピリオドのプレフィックスを付けることで、クラス メンバーに名前を付けます。 例えば次が挙げられます。

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

クラス メンバー IControl.Paint は、 IControl インターフェイス経由でのみ使用でき、 ISurface.PaintISurfaceでのみ使用できます。 どちらのメソッド実装も独立しており、どちらもクラスで直接使用できません。 例えば次が挙げられます。

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

明示的な実装は、2 つのインターフェイスがそれぞれプロパティやメソッドなどの同じ名前の異なるメンバーを宣言するケースを解決するためにも使用されます。 両方のインターフェイスを実装するには、コンパイラ エラーを回避するために、クラスでプロパティ Pまたはメソッド P、またはその両方に対して明示的な実装を使用する必要があります。 例えば次が挙げられます。

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

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

明示的なインターフェイスの実装では、定義されている型のメンバーとしてアクセスできないため、アクセス修飾子はありません。 代わりに、インターフェイスのインスタンスを介して呼び出された場合にのみアクセスできます。 明示的なインターフェイス実装にアクセス修飾子を指定すると、コンパイラ エラー CS0106 が発生します。 詳細については、「 interface (C# リファレンス)」を参照してください。

インターフェイスで宣言されたメンバーの実装を定義できます。 クラスがインターフェイスからメソッド実装を継承する場合、そのメソッドにはインターフェイス型の参照を介してのみアクセスできます。 継承されたメンバーは、パブリック インターフェイスの一部として表示されません。 次の例では、インターフェイス メソッドの既定の実装を定義します。

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

次の例では、既定の実装を呼び出します。

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

IControl インターフェイスを実装するクラスは、パブリック メソッドまたは明示的なインターフェイス実装として、既定のPaint メソッドをオーバーライドできます。

こちらも参照ください