收集物品的副作用或返回新的收藏?

时间:2015-04-14 14:28:40

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

我们说我有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类的集合更好吗?

4 个答案:

答案 0 :(得分:1)

两种选择都有其优点和缺点。两者都是"罚款"从某种意义上说它们没有任何问题,它们通常用在C#中。

选项1具有简单易用的巨大优势。您甚至可以保留对WriteItem实例的引用,并在处理后检查其状态。

选项2更清晰地分离了关注点:在选项1中,您需要向WriteItem类添加注释以定义哪些是"输入"哪些是"输出"属性。选项2不需要这样做。此外,选项2允许您使WriteItemProcessingResult成为不可变的,这是一个不错的属性。

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

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

并将其用作ProcessingResult<WriteItem>以及ProcessingResult<SomeOtherItem>

答案 1 :(得分:0)

你写的东西会起作用。您可以在集合中进行迭代时修改对象属性而不会产生副作用。

除非您需要保持原始集合的副本不受影响,否则我不会返回新的集合。

答案 2 :(得分:0)

我认为一切都取决于可读性。

当您调用ProcessItems时,该集合是否已更改?如果你调用这样的方法:

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

与这样称呼:

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

或只是更改您的方法名称:

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

最后,我的书中没有正确答案。你应该做适合你的应用程序。并考虑:如果另一个开发人员正在查看这段代码怎么办?他能否猜测这里发生的事情,或者他是否必须深入了解ProcessItems函数以获得应用程序的要点。

答案 3 :(得分:0)

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

为什么?

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

对我而言,因为你必须为WriteItem对象添加额外的属性才能支持处理器。这实际上在模型和处理器之间创建了一个不应存在的强耦合。

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

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

例如。

第1项 - 已加载

第1项 - 选择失败!

第1项 - 选择

第1项 - 已交付