明示的なインターフェイスの実装 (C# プログラミング ガイド)
同じシグネチャを持つメンバーがそれぞれ存在する 2 つのインターフェイスをクラスが実装した場合、そのメンバーをクラスで実装すると、両方のインターフェイスがそのメンバーをそれぞれの実装として使用することになります。次の例では、Paint へのすべての呼び出しは、同じメソッドを呼び出します。
class Test
{
static void Main()
{
SampleClass sc = new SampleClass();
IControl ctrl = (IControl)sc;
ISurface srfc = (ISurface)sc;
// The following lines all call the same method.
sc.Paint();
ctrl.Paint();
srfc.Paint();
}
}
interface IControl
{
void Paint();
}
interface ISurface
{
void Paint();
}
class SampleClass : IControl, ISurface
{
// Both ISurface.Paint and IControl.Paint call this method.
public void Paint()
{
Console.WriteLine("Paint method in SampleClass");
}
}
// Output:
// Paint method in SampleClass
// Paint method in SampleClass
// Paint method in SampleClass
ただし、2 つのインターフェイス メンバーが同一の機能を実行しない場合は、これらのインターフェイスの一方または両方の実装が不適切になる可能性があります。そこで、インターフェイス メンバーを明示的に実装し、特定のインターフェイス経由でのみ呼び出され、そのインターフェイスに固有のクラス メンバーを作成できます。このように実装するには、インターフェイスの名前とピリオドを使ってクラス メンバーに名前を付けます。次に例を示します。
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.Paint は ISurface 経由でのみ呼び出されます。これら 2 つのメソッド実装はそれぞれ独立しており、いずれもクラスで直接呼び出すことができません。次に例を示します。
// Call the Paint methods from Main.
SampleClass obj = new SampleClass();
//obj.Paint(); // Compiler error.
IControl c = (IControl)obj;
c.Paint(); // Calls IControl.Paint on SampleClass.
ISurface s = (ISurface)obj;
s.Paint(); // Calls ISurface.Paint on SampleClass.
// Output:
// IControl.Paint
// ISurface.Paint
明示的な実装は、次のように、プロパティやメソッドなどの同じ名前を持つ別々のメンバーを 2 つのインターフェイスがそれぞれ宣言するケースを解決する場合にも使用されます。
interface ILeft
{
int P { get;}
}
interface IRight
{
int P();
}
これら両方のインターフェイスを実装する場合、クラスでは、プロパティ P またはメソッド P の一方または両方に明示的な実装を適用して、コンパイラのエラーを回避する必要があります。次に例を示します。
class Middle : ILeft, IRight
{
public int P() { return 0; }
int ILeft.P { get { return 0; } }
}