我在尝试为同一个类实现接口(interface)两次时遇到编译器错误,如下所示:
public class Mapper<T1, T2> : IMapper<T1, T2>, IMapper<T2, T1>
{
/* implementation for IMapper<T1, T2> here. */
/* implementation for IMapper<T2, T1> here. */
}
错误:
'Mapper' cannot implement both 'IMapper' and 'IMapper' because they may unify for some type parameter substitutions.
为什么这个解决方法有效?我想知道我是已经解决了问题还是只是欺骗了编译器。
public class Mapper<T1, T2> : MapperBase<T1, T2>, IMapper<T1, T2>
{
/* implementation for IMapper<T1, T2> here. */
}
public class MapperBase<T1, T2> : IMapper<T2, T1>
{
/* implementation for IMapper<T2, T1> here. */
}
编辑:我已将 MyClass
、MyClassBase
和 IMyInterface
更新为 Mapper
、MapperBase
和 IMapper
来表示更真实的场景,在该场景中可能会出现此问题。
最佳答案
考虑这个实现:
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>
在同一个类(class)是不允许的。如果您尝试实现,例如 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>.
前缀),将无法使用编译时语法调用它。反射(reflection)是必要的。
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();
}
}
关于c# - 接口(interface)实现两次 "types may unify";为什么此解决方法有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22721763/