は、我々は、このインターフェイスに複数の一般的なタイプのために複数回を実装するクラスを作成することができ、以下の共変の汎用インターフェース共変インターフェイスを複数回実装する:この動作は適切に定義されていますか?
public interface IContainer<out T>
{
T Value { get; }
}
を考えます。私が興味を持っているシナリオでは、これらのジェネリック型は共通の基本型を共有しています。タイプIContainer<IPrint>
の参照を通じて、このクラスを使用するとき
public interface IPrint
{
void Print();
}
public class PrintA : IPrint
{
public void Print()
{
Console.WriteLine("A");
}
}
public class PrintB : IPrint
{
public void Print()
{
Console.WriteLine("B");
}
}
public class SuperContainer : IContainer<PrintA>, IContainer<PrintB>
{
PrintA IContainer<PrintA>.Value => new PrintA();
PrintB IContainer<PrintB>.Value => new PrintB();
}
は今、物事は面白く。
public static void Main(string[] args)
{
IContainer<IPrint> container = new SuperContainer();
container.Value.Print();
}
これは問題なくコンパイルされて実行され、「A」を出力します。私はspecで見つけた:
私は メンバーMが宣言されているインタフェースは、開始、各クラスまたは構造体Sを調べる によって決定される特定のインターフェイスメンバIMの実装Cと、一致が見つかるまで、 ためのCの各連続基本クラスを繰り返す:
- S は、I及びMと一致する、明示的なインターフェイスメンバーの実装 の宣言が含まれている場合、このメンバーが実装されIM
- SがMに一致する非静的パブリックメンバ の宣言が含まれている場合そうでない場合、このメンバーはIM
の実装である最初の箇条書きは、インタフェースから、関連するように見えます実装は明示的です。しかし、複数の候補がある場合にどの実装が選択されているかについては何も言及していません。
我々はIContainer<PrintA>
実装のための公共popertyを使用する場合には、さらに面白い:上記の仕様によると、今
public class SuperContainer : IContainer<PrintA>, IContainer<PrintB>
{
public PrintA Value => new PrintA();
PrintB IContainer<PrintB>.Value => new PrintB();
}
IContainer<PrintB>
による明示的なインターフェイスの実装がありますので、私は印刷にこれを期待します"B"。ただし、代わりにpublicプロパティを使用して、 "A"を印刷します。
同様に、IContainer<PrintA>
explicitlyとIContainer<PrintB>
をパブリックプロパティで実装すると、それでも "A"が出力されます。
出力が依存するのは、インターフェイスが宣言されている順序だけです。宣言を
に変更した場合public class SuperContainer : IContainer<PrintB>, IContainer<PrintA>
「B」がすべて印刷されます。
仕様が正しく定義されている場合、この動作を定義する仕様の部分はどれですか?
私はそれがどこかで指定されていると思いますが、私はそれを見ていません。 Eric Lippertさんは、[bleg](https://blogs.msdn.microsoft.com/ericlippert/2007/11/09/covariance-and-contravariance-in-c-part-ten-dealing-with-ambiguity/)を持っていました。長い間、誰かがこの問題を考えていました。あなたが派生することができます正確に仕様のどのテキストから –