この実装を検討してください。
public class MyClass<T1, T2> : IMyInterface<T1, T2>, IMyInterface<T2, T1>
{
/* implementation for IMyInterface<T1, T2> here. */
/* implementation for IMyInterface<T2, T1> here. */
}
何がMyClass<int, int>
実装されていますか?とが等しい場合に と を統合するため、IMyInterface<int, int>
2 回実装します。そのため、 と の両方を同じクラスに実装することは許可されていません。たとえばandを実装しようとすると、同じ理由が適用されます。型式は for を統一します。IMyInterface<T1, T2>
IMyInterface<T2, T1>
T1
T2
IMyInterface<T1, T2>
IMyInterface<T2, T1>
IMyInterface<int, T1>
IMyInterface<T2, double>
T1 = double, T2 = int
この実装を検討してください。
public class MyClass<T1, T2> : MyClassBase<T1, T2>, IMyInterface<T1, T2>
{
/* implementation for IMyInterface<T1, T2> here. */
}
public class MyClassBase<T1, T2> : IMyInterface<T2, T1>
{
/* implementation for IMyInterface<T2, T1> here. */
}
あなたがしたことは、 を優先するIMyInterface<T1, T2>
ことIMyInterface<T2, T1>
です。T1
とT2
が等しく、 のインスタンスがある場合、MyClass<T1, T2>
実装IMyInterface<T1, T2>
が選択されます。のインスタンスがある場合はMyBaseClass<T1, T2>
、IMyInterface<T2, T1>
実装が選択されます。
これは、動作を示すおもちゃのプログラムです。特にa_as_i.M(0, 1)
との動作に注意してa_as_b.M(0, 1)
ください。(メソッド名の前に を付けて) をI<T2, T1>
明示的に実装する場合、コンパイル時の構文を使用して呼び出すことはできません。反省は必要でしょう。B<T1, T2>
I<T2, T1>.
interface I<T1, T2>
{
void M(T1 x, T2 y);
}
class A<T1, T2> : B<T1, T2>, I<T1, T2>
{
public void M(T1 x, T2 y)
{
Console.WriteLine("A: M({0}, {1})", x, y);
}
}
class B<T1, T2> : I<T2, T1>
{
public void M(T2 x, T1 y)
{
Console.WriteLine("B: M({0}, {1})", x, y);
}
}
class Program
{
static void Main(string[] args)
{
//Outputs "A: M(0, 1)"
var a = new A<int, int>();
a.M(0, 1);
//Outputs "B: M(0, 1)"
var b = new B<int, int>();
b.M(0, 1);
//Outputs "A: M(0, 1)" because I<T1, T2>
//takes precedence over I<T2, T1>
var a_as_i = a as I<int, int>;
a_as_i.M(0, 1);
//Outputs "B: M(0, 1)" despite being called on an instance of A
var a_as_b = a as B<int, int>;
a_as_b.M(0, 1);
Console.ReadLine();
}
}