C# の
IEnumerator Interfaceのページによくわからないコードがあった。師匠に聞いてみると、明示的なインターフェイス実装というコーディング方法らしい。ちょっと試してみた。
通常のインターフェイス実装
public interface IFoo
{
string GetSome();
}
public class Foo : IFoo
{
public string GetSome()
{
return "Foo!";
}
}
:
static void Main(string[] args)
{
IFoo foo = new Foo();
Console.WriteLine($"IFoo: {foo.GetSome()}");
Console.WriteLine($"Foo : {((Foo)foo).GetSome()}");
:
結果は普通に
IFoo: Foo!
Foo : Foo!
明示的なインターフェイス実装
さて問題の謎実装。明示的なインターフェイス実装というらしい。
public class SpecialFoo : IFoo
{
string IFoo.GetSome()
{
return "Special Foo!";
}
}
:
static void Main(string[] args)
{
IFoo specialFoo = new SpecialFoo();
Console.WriteLine($"IFoo: {specialFoo.GetSome()}");
// Console.WriteLine($"SpecialFoo : {((SpecialFoo)specialFoo).GetSome()}"); // コンパイル不可
:
インターフェイス経由でメソッドを呼ぶと問題ないが、実装クラスにキャストすると、GetSome()
などないといわれる。なんとも面白い動きだ。実装クラスから、インターフェイス実装を隠したいときとかに使うらしい。
複数インターフェイスの実装
複数インターフェイスを実装したらおもしろいことができる。
public interface IFoo
{
string GetSome();
}
public interface IBar
{
string GetSome();
}
public class FooBar : IFoo, IBar
{
string IFoo.GetSome()
{
return "IFoo.FooBar";
}
string IBar.GetSome()
{
return "IBar.FooBar";
}
public string GetSome()
{
return "FooBar";
}
}
:
static void Main(string[] args)
{
FooBar fooBar = new FooBar();
Console.WriteLine($"IFoo: {((IFoo)fooBar).GetSome()}");
Console.WriteLine($"IBar: {((IBar)fooBar).GetSome()}");
Console.WriteLine($"FooBar : {fooBar.GetSome()}");
:
実行結果
IFoo: IFoo.FooBar
IBar: IBar.FooBar
FooBar : FooBar
なんとも面白い仕様!さて、コレクションの調査に戻る。