【问题标题】:Side effects on collection items or return a new collection?对收藏品产生副作用或返回新收藏?
【发布时间】:2015-06-20 05:18:50
【问题描述】:

假设我有一个如下所示的 WriteItem 类:

public class WriteItem
{
    public string Name { get; set; }
    public object Value { get; set; } 
    public int ResultCode { get; set; }
    public string ErrorMessage { get; set;}
}

我需要处理每个项目并设置其ResultCodeErrorMessage 属性,并且我想定义一个类似的方法:

public void ProcessItems(WriteItemCollection items)
{
    foreach(var item in items)
    {
        // Process each item and set its result.
    }
}

每个项目的处理由另一个类完成。

这是最好的方法吗?

或者让该方法返回一个自定义 Result 类的集合更好?

【问题讨论】:

  • "best" 是非常主观的 - 但我认为您的方法没有任何问题。
  • "best" 适合您的需求
  • 刚刚编辑指出另一个类负责项目的处理。

标签: c# parameters return-type side-effects


【解决方案1】:

这两种选择都有其优点和缺点。两者都“很好”,因为它们没有任何问题,并且它们通常用于 C#。

选项 1 的一大优点是简单易行。您甚至可以保留对 WriteItem 实例的引用并在处理后检查其状态。

选项 2 具有更清晰的关注点分离:在选项 1 中,您需要将 cmets 添加到 WriteItem 类中以定义哪些是“输入”属性,哪些是“输出”属性。选项 2 不需要。此外,选项 2 允许您使 WriteItemProcessingResult 不可变,这是一个不错的属性。

选项2的扩展性也更强:如果你想处理WriteItems以外的东西(具有相同的返回选项),你可以定义一个类

class ProcessingResult<T>
{
    public T Item { get; set; }
    public int ResultCode { get; set; }
    public string ErrorMessage { get; set; }
}

并将其用作ProcessingResult&lt;WriteItem&gt;ProcessingResult&lt;SomeOtherItem&gt;

【讨论】:

    【解决方案2】:

    您所写的将起作用。在集合中迭代时,您可以修改对象属性而不会产生副作用。

    除非您需要保留原始收藏的副本,否则我不会退回新收藏。

    【讨论】:

      【解决方案3】:

      我认为这一切都归结为可读性。

      当你调用 ProcessItems 时,是不是很明显集合发生了变化?如果你这样调用方法:

      var items = GetItemsFromSomewhere();
      ProcessItems(items);
      

      相对于这样称呼它:

      var items = GetItemsFromSomewhere();
      items = ProcessItems(items);
      

      或者只是改变你的方法名:

      var items = GetItemsFromSomewhere();
      items = UpdateItemStatuses(items);
      

      最后,在我的书中,这个问题没有正确的答案。您应该做适合您的应用程序的事情。并考虑一下:如果另一个开发人员正在查看这段代码怎么办?他能推测出这里发生了什么吗,还是必须深入到 ProcessItems 函数中才能了解应用程序的要点。

      【讨论】:

        【解决方案4】:

        最好返回一个新的结果类。

        为什么?

        正如其他人所说,您正在修改集合并且它不是很清楚。但对我来说,这不是主要原因。您可以拥有修改对象的进程。

        对我来说,这是因为您必须向 WriteItem 对象添加额外的属性才能支持处理器。这实际上在模型和不应该存在的处理器之间创建了强耦合。

        考虑你有另一种方法ProcessItems_ForSomeOtherPurpose(List&lt;WriteItem&gt; items) 你扩展你的ResultCode int 以获得更有意义的值吗?您是否添加了另一个属性ResultCode_ForSomeOtherPurpose?如果您需要使用多个处理器多次处理同一个项目怎么办?

        我会给你的模型一个 ID。然后你可以针对它记录多个进程

        例如。

        项目 1 - 已加载

        项目 1 - 拣货失败!

        项目 1 - 挑选

        项目 1 - 已交付

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-02-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多