【发布时间】:2011-10-25 12:48:11
【问题描述】:
我知道,类实现中的隐藏成员可能会导致调用“错误”成员的情况,具体取决于我如何转换我的实例,但是对于接口,我认为这不是一个问题,我发现我自己经常写这样的接口:
public interface INode
{
IEnumerable<INode> Children { get; }
}
public interface INode<N> : INode
where N : INode<N>
{
new IEnumerable<N> Children { get; }
}
public interface IAlpha : INode<IAlpha>
{ }
public interface IBeta : INode<IBeta>
{ }
我的代码中有一些地方只知道INode,所以孩子也应该是INode类型。
在其他地方我想了解具体类型 - 在我的示例 IAlpha 和 IBeta 接口的实现中,我希望子项的类型与其父项相同。
所以我像这样实现NodeBase 类:
public abstract class NodeBase<N> : INode<N>
where N : INode<N>
{
protected readonly List<N> _children = new List<N>();
public IEnumerable<N> Children
{
get { return _children.AsEnumerable(); }
}
IEnumerable<INode> INode.Children
{
get { return this.Children.Cast<INode>(); }
}
}
在实际实现中没有阴影,仅在接口中。
IAlpha 和 IBeta 的具体实例如下所示:
public class Alpha : NodeBase<Alpha>, IAlpha
{
IEnumerable<IAlpha> INode<IAlpha>.Children
{
get { return this.Children.Cast<IAlpha>(); }
}
}
public class Beta : NodeBase<Beta>, IBeta
{
IEnumerable<IBeta> INode<IBeta>.Children
{
get { return this.Children.Cast<IBeta>(); }
}
}
同样,在实现中没有阴影。
我现在可以像这样访问这些类型:
var alpha = new Alpha();
var beta = new Beta();
var alphaAsIAlpha = alpha as IAlpha;
var betaAsIBeta = beta as IBeta;
var alphaAsINode = alpha as INode;
var betaAsINode = beta as INode;
var alphaAsINodeAlpha = alpha as INode<Alpha>;
var betaAsINodeBeta = beta as INode<Beta>;
var alphaAsINodeIAlpha = alpha as INode<IAlpha>;
var betaAsINodeIBeta = beta as INode<IBeta>;
var alphaAsNodeBaseAlpha = alpha as NodeBase<Alpha>;
var betaAsNodeBaseBeta = beta as NodeBase<Beta>;
现在每个变量都有正确的强类型Children 集合。
所以,我的问题很简单。使用这种模式的界面成员的阴影是好是坏还是丑陋?为什么?
【问题讨论】:
-
为什么不简单地使用类型参数来确定孩子的类型。然后 INode
仍然具有相同的语义,但您根本不需要阴影 -
@Rune - “类型参数”是什么意思?
-
@Enigmativity:我已经编辑了我的答案以简化 NodeBase 对 INode.Children 的实现——我已经弄清楚了我之前缺少的东西。
-
@Jon - 谢谢。非常感谢。
标签: c# .net oop generics shadowing