在派生类

时间:2017-06-07 18:15:46

标签: c#

我有一个抽象类:

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显示两个具有相同名称和相同类型的相同属性!

Screenshot

循环代码:

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();
    }

希望你帮忙!对不起床英语:)

1 个答案:

答案 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();
    ...
}