给定此“ IHandle”接口和两个要处理的类:
interface IHandle<T>
{
void Handle(T m);
}
class M1
{
public int Id;
}
class MReset
{
}
我想创建一个通用的基础来处理“重置”以及管理M1实例:
class HandlerBase<T> :
IHandle<MReset>,
IHandle<T> where T : M1
{
protected int Count;
void IHandle<T>.Handle(T m)
{
++Count;
Console.WriteLine("{0}: Count = {0}", m.Id, Count);
}
void IHandle<MReset>.Handle(MReset m)
{
Count = 0;
}
}
由于编译器认为T可能是“ MReset”,因此无法编译,因此输出:
错误CS0695:“ HandlerBase”无法同时实现“ IHandle”和“ IHandle”,因为它们可能会为某些类型参数替换统一
这本身有点奇怪,因为我看不到T可能是MReset类型,因为T必须是M1类型。但是好吧,我可以接受编译器比我更聪明:-)
编辑:编译器并不比我更聪明:-)根据关于为什么在CS0695中导致此结果的注释。我们有“在确定所有可能的构造类型时不考虑约束声明”。
现在,我交换接口声明:
class HandlerBase<T> :
IHandle<T> where T : M1,
IHandle<MReset>
{
... same as before ..
}
突然,我收到一条不同的错误消息,指出我无法实现IHandle.Handle(MReset m),因为类声明未声明其正在实现该接口:
错误CS0540:“ HandlerBase.IHandle <...>。Handle(MReset)”:包含类型未实现接口“ IHandle”
问题:为什么声明顺序会产生不同的影响?第二个示例出了什么问题?
最后,有一个解决方案:
class HandlerBase :
IHandle<MReset>
{
protected int Count;
void IHandle<MReset>.Handle(MReset m)
{
Count = 0;
}
}
class Handler<T> : HandlerBase,
IHandle<T> where T : M1
{
void IHandle<T>.Handle(T m)
{
++Count;
Console.WriteLine("{0}: Count = {0}", m.Id, Count);
}
}
但是该解决方案仅在HandlerBase
实现时才有效-如果先实现IHandle<MReset>
通用接口IHandle<T>
则无效HandlerBase
。为什么呢
编辑:IHandle<T>
在HandlerBase
中实现确实起作用(如果我已经显示了代码,则可能有人看到了)。这有效:
class HandlerBase<T> :
IHandle<T> where T : M1
{
protected int Count;
void IHandle<T>.Handle(T m)
{
++Count;
Console.WriteLine("Type = {0}, Id = {1}, Count = {2}", GetType(), m.Id, Count);
}
}
class Handler<T> : HandlerBase<T>,
IHandle<MReset>
where T : M1
{
void IHandle<MReset>.Handle(MReset m)
{
Count = 0;
Console.WriteLine("RESET");
}
}
不幸的是,我的第二堂课声明是这样的:
class Handler<T> : HandlerBase<T> where T : M1,
IHandle<MReset>
{
void IHandle<MReset>.Handle(MReset m)
{
Count = 0;
Console.WriteLine("RESET");
}
}
注意where T : M1
:-)位置的细微差别。最后一个示例声明T必须实现IHandle<MReset>
(除之外M1
)。h!
问题已解决-我发现了细微的差别。当声明的顺序被交换我不动where T : M1
,因为IHandle<MReset>
约束,则最终被应用到的T,而不是类的声明:
class HandlerBase<T> :
IHandle<T> where T : M1,
IHandle<MReset>
{
... same as before ..
}
正确的重新排序应该是:
class HandlerBase<T> :
IHandle<T>,
IHandle<MReset>
where T : M1
{
... same as before ..
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句