使用特性与计算更改值的方法
本文关键字:方法 计算 | 更新日期: 2023-09-27 18:26:07
是否有在调用时使用属性计算值的约定?例如,如果我的类包含一个整数列表,并且我有一个属性Average,那么当从列表中添加/删除/修改一个整数时,平均值可能会改变,这样做吗:
private int? _ave = null;
public int Average
{
get
{
if (_ave == null )
{
double accum = 0;
foreach (int i in myList)
{
accum += i;
}
_ave = accum / myList.Count;
return (int)_ave;
}
else
{
return (int)_ave;
}
}
}
其中,如果以可能更改平均值的方式修改myList,则_ave设置为null。。。
与平均值的方法调用相比,有任何传统的优点/缺点吗?
我基本上只是想知道这方面的约定是什么,因为我正在创建一个具有只能计算一次的特定属性的类。我喜欢访问这些属性的类能够访问属性而不是方法的想法(因为IMO似乎更可读,将类似average的东西视为属性而非方法),但我可以看到这可能会变得复杂,尤其是在确保_ave适当设置为null时。
约定为:
- 如果调用要花费比简单地读取字段并复制其中的值多得多的时间,那么将其作为一个方法。属性应该快
- 如果成员表示类的操作或能力,则将其设为方法
- 如果对getter的调用使状态发生变化,则将其作为一个方法。属性是在调试器中自动调用的,在调试程序时让调试器在程序中引入突变是非常令人困惑的
- 如果在不寻常的时候调用时调用不健壮,则将其作为一个方法。例如,在构造函数和终结器中使用时,属性需要继续工作。再次考虑调试器;如果您正在调试构造函数,那么检查调试器中的属性应该是可以的,即使它实际上还没有初始化
- 如果调用can失败,则将其作为一个方法。属性不应引发异常
在你的具体情况下,它处于临界状态。您第一次执行的操作可能很长,然后缓存结果,因此即使最坏的情况很慢,摊销时间也可能很快。你们正在改变状态,但再一次,以一种非破坏性的方式。似乎你可以把它描述为一个集合的性质,而不是这个集合的"能力"。我个人倾向于将其作为一种方法,但如果你有充分的理由将其作为财产,我不会极力反对。
关于您的具体实现:我更倾向于使用64位整数作为累加器,而不是64位双精度;与长的64位相比,双精度只有53位的整数精度。
微软对使用方法的建议:
使用方法
- 如果呼叫有副作用
- 如果每次调用都返回不同的值
- 如果打电话需要很长时间
- 如果操作需要参数(索引器除外)
如果计算值是对象的属性,则使用属性。
在你的情况下,我认为具有隐含懒惰计算的属性将是一个不错的选择。
是的…get访问器不应以任何方式修改对象的状态。当然,返回的值是可以计算的,并且您可能有大量的代码。但是,简单地访问一个值根本不应该影响包含实例的状态。
在这种特殊的情况下,为什么不在构造类实例时计算所有内容呢?或者提供一个专用的方法来强制类这样做
现在我想,在某些特定的情况下,这种行为是可以的。这可能就是其中之一。但是,如果没有看到代码的其余部分(以及它的使用方式),就无法判断。