如果我在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));
}
}
}
有没有办法对此进行优化?
答案 0 :(得分:3)
是的,每次调用属性时,它都会执行循环。
属性实际上只是方法调用的语法糖。非常好的很好的语法糖,但只有糖。
您可能希望更改CartViewModel
以避免直接暴露列表 - 而是将列表保密,提供一些适当的方法来改变它(例如Add
和Clear
方法),可能会让它自己实现IEnumerable<CartViewItem>
,并在列表发生变异时跟踪小计和折扣。那假设CartViewItem
是不可变的,当然......
或者(正如约翰所建议的那样),只是让您更明显地实际工作,将属性更改为ComputeTotal()
,ComputeDiscount()
和ComputeSubTotal()
方法。
答案 1 :(得分:2)
我会建议“不要做那种”方法。
属性适用于被访问的数据在性能和语义方面“几乎像一个字段”的情况。它们肯定不意味着财产隐藏了一个更昂贵的操作正在执行的事实。
用方法替换这些属性,并查看调用代码是否发生了很大变化。你正在做一些可能很昂贵的事情会更清楚。
根据引用的频率,我可能会进一步完全内联属性。这可能表明调用者有一些优化。