【问题标题】:Logic in get part of property. Good practice?获取部分财产的逻辑。好习惯?
【发布时间】:2010-10-04 11:55:14
【问题描述】:

在将我的 xaml 数据绑定到某些数据时,我经常使用属性的“获取”部分来执行一些逻辑。就像给出一个列表的总和或检查某事是否为正。

例如:

public List<SomeClass> ListOfSomeClass{get;set;}

public double SumOfSomeClass
{
  get
  {
    return ListOfSomeClass.Sum(s => s.Totals);
  }
}

public bool SumPositive
{
  get
  {
    if(SumOfSomeClass >= 0)
      return true;
    else
      return false;
  }
}

这样我可以绑定到 SumPositive 和 SumOfSomeClass。这被认为是好的做法吗?即使它变得比这更复杂?还是调用一个方法并返回结果会更好?调用另一个类甚至数据库呢?

【问题讨论】:

    标签: c# wpf data-binding properties


    【解决方案1】:

    我会小心地将任何逻辑放在属性的 Getter 中。做的越贵,就越危险。其他开发人员希望 getter 立即返回值,就像从成员变量中获取值一样。我见过很多例子,开发人员在循环的每次迭代中都使用一个属性,认为他们只是在取回一个值,而该属性实际上做了很多工作。这可能会大大减慢您的代码执行速度。

    【讨论】:

      【解决方案2】:

      我喜欢您的命名约定,并且我完全同意在属性获取器中使用您的示例等内容,如果您要提供用于绑定的 API。

      我不同意其他人关于将代码移动到方法中的观点,因为它的计算量很大 - 这不是我曾经做过的区分,也没有听到其他人认为在方法中意味着更慢而不是属性。

      我确实相信属性在调用它们的对象上应该没有副作用。要保证它们对更广泛的环境没有影响要困难得多——即使是一个相对微不足道的属性也可能会将数据拉入内存,或者至少会改变处理器缓存或虚拟机状态。

      【讨论】:

        【解决方案3】:

        在 getter/setter 中有复杂的逻辑不是一个好习惯。我建议将复杂的逻辑转移到单独的方法中(例如 GetSumOfXYZ())并在属性访问器中使用memoization

        您可以通过使用ObjectDataProvider 来避免复杂的属性 - 它允许您定义提取一些数据的方法。

        【讨论】:

          【解决方案4】:

          请把那个 getter 改成这样:

          public bool SumPositive
          {
            get
            {
               return SumOfSomeClass >= 0;
            }
          }
          

          您已经在使用布尔表达式,无需显式返回 true 或 false

          【讨论】:

          • 我在代码中实际使用的内容。在示例中,它应该“看起来”更复杂;)
          【解决方案5】:

          是的,除非它是可能影响性能的操作。在这种情况下,您应该改用方法(因为最终用户更直观地认为方法可能很慢而属性会很快)

          【讨论】:

            【解决方案6】:

            我认为在 Getter 和 Setter 中应该有某种程度的逻辑,否则你只有一种复杂的方式来声明你的成员为 public。

            【讨论】:

              【解决方案7】:

              取决于...如果这是在域实体上,那么我不赞成在 getter 中使用复杂的逻辑,尤其是在 setter 中。使用方法(对我而言)向实体的消费者发出信号表明正在执行操作,而 getter 发出简单检索的信号。

              现在,如果这个逻辑在 ViewModel 中,那么我认为 getter 方面更容易被原谅/预期。

              【讨论】:

                【解决方案8】:

                对于集合中的字段或其他属性的基本计算,可以在 Get 属性中执行此操作。正如其他人所说,真正的逻辑永远不应该在 getter 中完成。

                【讨论】:

                  【解决方案9】:

                  我没有看到任何直接问题(除非列表非常庞大),但如果可能的话,我会亲自使用 myInstance.SomeList.Sum() 方法 (.net >= 2.0)。

                  【讨论】:

                    【解决方案10】:

                    property getter 应该是快速且幂等的(即不应在那里执行破坏性操作)。尽管迭代内存中的对象集合非常好,但我不建议在 getset 部分中进行任何繁重的工作。说到迭代,我仍然会缓存结果以节省几毫秒。

                    【讨论】:

                    • “节省几毫秒” - 纳秒?
                    • 幂等的含义比这更广泛——它意味着你通过重复调用操作得到相同的结果,而不是受到记忆状态的影响。 en.wikipedia.org/wiki/Idempotent
                    【解决方案11】:

                    我说是的,但尝试将结果存储在 ListOfSomeClass.Sum(s => s.Totals) 的私有变量中。特别是如果您多次使用它。

                    【讨论】:

                      猜你喜欢
                      • 2020-04-21
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多