使用循环时获取属性优化

时间:2011-05-18 18:44:46

标签: c# optimization

如果我在get属性中使用循环,这是否意味着每次调用get属性时,它都会执行循环?例如,如果我调用CartViewModel.Total,这是否意味着它在SubTotal和Discount中执行循环?

public class CartViewModel
{
    public decimal SubTotal { get { return CartViewItems.Sum(c => c.Price); } }
    public decimal Discount { get { return CartViewItems.Sum(c => Total-SubTotal); } }
    public decimal Total { get { return SubTotal-Discount; } }

    public List<CartViewItem> CartViewItems { get; set; }
}

public class CartViewItem
{
    public decimal Price { get; set; }
    public int ProductId { get; set; }
    public int Quantity { get; set; }
public float DiscountPercent {get; set;}
    public decimal SubTotal { get { return Price*Quantity; } }

    public decimal Total
    {
        get
        {
            return Convert.ToDecimal(((float)Price * (1 - (DiscountPercent / 100))
                       * Quantity));
        }
    }
}

有没有办法对此进行优化?

2 个答案:

答案 0 :(得分:3)

是的,每次调用属性时,它都会执行循环。

属性实际上只是方法调用的语法糖。非常好的很好的语法糖,但只有糖。

您可能希望更改CartViewModel以避免直接暴露列表 - 而是将列表保密,提供一些适当的方法来改变它(例如AddClear方法),可能会让它自己实现IEnumerable<CartViewItem>,并在列表发生变异时跟踪小计和折扣。那假设CartViewItem是不可变的,当然......

或者(正如约翰所建议的那样),只是让您更明显地实际工作,将属性更改为ComputeTotal()ComputeDiscount()ComputeSubTotal()方法。

答案 1 :(得分:2)

我会建议“不要那种”方法。

属性适用于被访问的数据在性能和语义方面“几乎像一个字段”的情况。它们肯定意味着财产隐藏了一个更昂贵的操作正在执行的事实。

用方法替换这些属性,并查看调用代码是否发生了很大变化。你正在做一些可能很昂贵的事情会更清楚。

根据引用的频率,我可能会进一步完全内联属性。这可能表明调用者有一些优化。