我有一个抽象类:
public abstract class Node
{
protected readonly List<Node> Nodes = new List<Node>();
public Node[] ChildNodes => Nodes.ToArray();
...
}
来自他:
public sealed class NodeArray<T> : Node where T: Node
{
private readonly List<T> _array = new List<T>();
private new List<Node> Nodes => _array.Cast<Node>().ToList();
public new Node[] ChildNodes => _array.Cast<Node>().ToArray();
...
}
Node.Nodes列表可能包含NodeArray&lt; Smth&gt;通过。 但是,当我试图递归枚举节点,并且我得到一个NodeArray类型时,它返回空的ChildNodes值(基类我猜)。 当我调试下面的代码时,Intellisense显示两个具有相同名称和相同类型的相同属性!
循环代码:
protected void LoadNode(Node node, XmlNode xmlNode)
{
foreach (XmlNode childNode in xmlNode.ChildNodes)
{
if (childNode.HasChildNodes)
{
var child = node.ChildNodes.First(p => p.Name == childNode.Name); // <----- Stuck here
if(child == null)
throw new Exception("Unknown child " + childNode.Name + " in Node " + node.Name);
LoadNode(child, childNode);
}
else
{
node[childNode.Name] = childNode.Value;
}
}
node.Load();
}
希望你帮忙!对不起床英语:)
答案 0 :(得分:1)
您的问题可能是您正在使用成员隐藏(使用new
关键字)而不是覆盖。在隐藏成员的情况下,尽管具有相同的名称,但基类和派生类包含属性的单独定义。因此,如果您创建NodeArray<T>
实例,填充其_array
集合,然后将其作为Node
引用传递,则ChildNodes
属性仍将返回空集合Node.Nodes
基本属性,而不是您期望的NodeArray<T>._array
字段。
要解决此问题,请切换到使用虚拟和已覆盖的成员,如下所示:
public abstract class Node
{
protected virtual List<Node> Nodes { get; } = new List<Node>();
public virtual Node[] ChildNodes => Nodes.ToArray();
...
}
public sealed class NodeArray<T> : Node where T: Node
{
private readonly List<T> _array = new List<T>();
protected override List<Node> Nodes => _array.Cast<Node>().ToList();
public override Node[] ChildNodes => _array.Cast<Node>().ToArray();
...
}