c#中计算属性的两种方法

本文关键字:两种 方法 属性 计算 | 更新日期: 2023-09-27 17:50:30

大家好。我不明白哪一种方法是最好的:在访问它的那一刻计算属性还是在每次必须更改时计算属性。例如,实现Level属性的两种方法:

public class TreeNode
{
    public TreeNode()
    {
        ChildNodes = new Collection<TreeNode>();
    }
    public Collection<TreeNode> ChildNodes { get; private set; }
    public TreeNode ParentNode { get; private set; }
    public int Level
    {
        get
        {
            if (ParentNode != null) return ParentNode.Level + 1;
            else return 0;
        }
    }
    pubic void Add(TreeNode node)
    {
        this.ChildNodes.Add(node);
        node.ParentNode = this;
    }
    public void TraverseNodes(Action<TreeNode> action)
    {
        action(this);
        foreach (CTreeNode child in this.ChildNodes)
        {
            child.TraverseNodes(action);
        }
    }
}

最好用上面还是下面?

public class TreeNode
{
    public TreeNode()
    {
        ChildNodes = new Collection<TreeNode>();
        Level = 0;
    }
    public Collection<TreeNode> ChildNodes { get; private set; }
    public TreeNode ParentNode { get; private set; }
    public int Level { get; private set; }
    pubic void Add(TreeNode node)
    {
        this.ChildNodes.Add(node);
        node.ParentNode = this;
        node.TraverseNodes(eachNode =>
        {
            eachNode.Level += this.Level + 1;
        });
    }
    public void TraverseNodes(Action<TreeNode> action)
    {
        action(this);
        foreach (CTreeNode child in this.ChildNodes)
        {
            child.TraverseNodes(action);
        }
    }
}

c#中计算属性的两种方法

你可以问自己一些问题:

  • 是否有额外的开销与提前计算所有节点的属性值相关?
  • 多长时间访问一次属性?

在您的例子中,您提出的第二个解决方案有一个开销——每当树发生变化时,您都要为潜在的大量节点调用traversenode。这是昂贵的。

另一方面,每次访问节点时都要按需递归地计算属性(你的第一个解决方案)——如果你可能经常访问Level属性,这就会成为一个问题。

所以这完全取决于你将使用多少Level属性。如果您经常使用它,并且不经常向树中添加内容,请考虑使用第二种解决方案。

如果您经常更改树,并且不太关注Level,那么使用第一种方法可能会更好。

但是,最好的方法是在典型的使用场景中尝试这两种方法,并对进行基准测试。然后你会得到一个明确的答案。