使用属性与计算更改值的方法

时间:2012-02-29 21:31:37

标签: c# coding-style conventions

是否有关于是否使用属性来计算通话值的约定?例如,如果我的类包含一个整数列表,并且我有一个属性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,将平均值视为属性而不是方法),但我可以看到这里可能会有问题,特别是在确保_ave被适当地设置为null时。

3 个答案:

答案 0 :(得分:12)

惯例是:

  • 如果调用比简单地读取字段并复制其中的值要花费更多的时间,请将其设为方法。属性应该快速
  • 如果该成员代表该类的操作能力,请将其设为方法。
  • 如果调用getter 变异状态,请将其设为方法。在调试器中自动调用属性,调试器在调试时在程序中引入突变是非常令人困惑的。
  • 如果在异常时间呼叫时呼叫不健全,则将其设为方法。例如,当在构造函数和终结器中使用时,属性需要继续工作。再考虑调试器;如果你正在调试一个构造函数,那么你应该可以检查调试器中的属性,即使它实际上还没有被初始化。
  • 如果呼叫失败,则将其设为方法。属性不应该抛出异常。

在您的具体情况下,它是临界的。您第一次执行可能很长的操作然后缓存结果,因此即使最坏情况时间很慢,分摊的时间也可能非常快。你正在以一种非破坏性的方式改变状态。看起来你可以将它描述为集合的属性而不是集合的“能力”。我个人倾向于把它作为一种方法,但如果你有充分的理由将其作为财产,我就不会非常努力。

关于你的具体实现:我更倾向于使用64位整数作为累加器而不是64位双精度;与长整数的64位相比,double只有53位的整数精度。

答案 1 :(得分:3)

Microsoft建议使用方法:

使用方法

  • 如果打电话有副作用
  • 如果它返回不同的值,则每次调用
  • 如果需要很长时间才能致电
  • 如果操作需要参数(索引器除外)

如果计算值是对象的属性,则使用属性。

在你的情况下,我认为具有隐式延迟计算的属性是不错的选择。

答案 2 :(得分:2)

是的,有一个get访问者不应该以任何方式修改对象的状态。当然可以计算返回的值,并且您可能在那里有大量代码。但是,简单地访问值不应该影响包含实例的状态。

在这种特殊情况下,为什么不在构建类实例时计算所有内容呢?或者提供一种强制课程的专用方法。

现在我想可能会有非常具体的情况,这种行为是可以的。这可能就是其中之一。但是,如果没有看到代码的其余部分(以及它的使用方式),就无法分辨。