考虑这个实现:
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>
了两次,因为IMyInterface<T1, T2>
和IMyInterface<T2, T1>
统一时T1
和T2
相等。这就是为什么不允许在同一个类上实现两者的原因IMyInterface<T1, T2>
。IMyInterface<T2, T1>
例如,如果您尝试实现IMyInterface<int, T1>
and ,同样的推理也适用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>
over 上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();
}
}