尝试为同一个类实现两次接口时遇到编译器错误,如下所示:
public class Mapper<T1, T2> : IMapper<T1, T2>, IMapper<T2, T1>
{
/* implementation for IMapper<T1, T2> here. */
/* implementation for IMapper<T2, T1> here. */
}
错误:
'Mapper'无法同时实现'IMapper'和'IMapper',因为它们可能会统一某些类型参数替换 .
为什么这个解决方法有效?我想知道我是否已经解决了问题或者只是欺骗了编译器 .
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. */
}
EDIT :我已将 MyClass
, MyClassBase
和 IMyInterface
更新为 Mapper
, MapperBase
和 IMapper
,以表示此问题可能出现的更真实场景 .
3 回答
考虑这个实现:
MyClass<int, int>
实施了什么?它实现IMyInterface<int, int>
两次,因为IMyInterface<T1, T2>
和IMyInterface<T2, T1>
在T1
和T2
相等时统一 . 这就是为什么不允许在同一个类上实现IMyInterface<T1, T2>
和IMyInterface<T2, T1>
的原因 . 如果您尝试实现相同的推理,例如,IMyInterface<int, T1>
和IMyInterface<T2, double>
:类型表达式统一为T1 = double, T2 = int
.考虑这个实现:
你所做的是优先考虑
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)
的行为 . 如果要在B<T1, T2>
上显式实现I<T2, T1>
(通过在I<T2, T1>.
前面加上方法名称),则无法使用编译时语法调用它 . 反思是必要的 .你没有't tricked the compiler, you'已经做到这一点,所以你不会有竞争的功能定义 . 假设您的界面具有
string Convert(T1 t1, T2 t2)
函数 . 使用您的第一个(非法)代码,如果您执行MyClass<string, string>
,则您将拥有2个相同功能的实例 . 使用您的基类,这两个实例将位于MyClassBase
和MyClass
中,因此MyClass
中的一个将隐藏另一个实例,而不是与之冲突 . 我想,无论是否有效取决于你 .我认为问题是由于编译器无法显示如果其中一个
T1
或T2
类型是另一个类型的后代(或者是相同类型),则应该调用哪些已实现的方法 .想象一下如果你实例化类
MyClass<int, int>
应该怎么做 .