collection 项目或 return 新 collection 的副作用?
Side effects on collection items or return a new collection?
假设我有一个 WriteItem
class 看起来像这样:
public class WriteItem
{
public string Name { get; set; }
public object Value { get; set; }
public int ResultCode { get; set; }
public string ErrorMessage { get; set;}
}
我需要处理每个项目并设置其 ResultCode
和 ErrorMessage
属性,我想定义一个类似于此的方法:
public void ProcessItems(WriteItemCollection items)
{
foreach(var item in items)
{
// Process each item and set its result.
}
}
每个项目的处理由另一个class完成。
这是最好的方法吗?
还是让自定义结果 class 的方法 return 成为 collection 更好?
你写的会起作用的。在集合中迭代时,您可以修改对象属性而不会产生副作用。
我不会return一个新的集合,除非你需要保持原始集合的副本不变。
两种选择各有优缺点。两者都是"fine",因为它们没有任何问题,而且它们在 C# 中很常用。
选项 1 的一大优点是简单易行。您甚至可以保留对 WriteItem
实例的引用并在处理后检查其状态。
选项 2 具有更清晰的关注点分离:在选项 1 中,您需要在 WriteItem
class 中添加注释以定义哪些是 "input" 哪些是 "output" 属性。选项 2 不需要。此外,选项 2 允许您使 WriteItem
和 ProcessingResult
不可变,这是一个不错的 属性.
选项 2 也更具可扩展性:如果你想处理除 WriteItem
s 以外的东西(使用相同的 return 选项),你可以定义一个 class
class ProcessingResult<T>
{
public T Item { get; set; }
public int ResultCode { get; set; }
public string ErrorMessage { get; set; }
}
并将其用作 ProcessingResult<WriteItem>
以及 ProcessingResult<SomeOtherItem>
。
我认为这一切都归结为可读性。
当你调用 ProcessItems 时,是否很明显集合发生了变化?如果你这样调用方法:
var items = GetItemsFromSomewhere();
ProcessItems(items);
与这样称呼:
var items = GetItemsFromSomewhere();
items = ProcessItems(items);
或简单地更改您的方法名称:
var items = GetItemsFromSomewhere();
items = UpdateItemStatuses(items);
这个问题在我的书中最终没有正确答案。您应该做适合您的应用程序的事情。并考虑:如果另一个开发人员正在查看这段代码怎么办?他能否推测这里发生了什么,或者他是否必须深入研究 ProcessItems 函数才能了解应用程序的要点。
最好return一个新的结果class。
为什么?
正如其他人所说,您正在修改集合,但不是很清楚。但对我来说这不是主要原因。您可以拥有修改对象的进程。
对我来说,这是因为您必须向 WriteItem 对象添加额外的属性才能支持处理器。这实际上在模型和处理器之间创建了一个不应该存在的强耦合。
考虑一下您有另一种方法 ProcessItems_ForSomeOtherPurpose(List<WriteItem> items)
您是否扩展了 ResultCode
int 以获得更有意义的值?你再添加一个 属性 ResultCode_ForSomeOtherPurpose
吗?如果您需要使用多个处理器多次处理同一个项目怎么办?
我会给你的模型一个 ID。然后你可以针对它记录多个进程
例如。
项目 1 - 已加载
项目 1 - 取货失败!
项目 1 - 已选择
项目 1 - 已交付
假设我有一个 WriteItem
class 看起来像这样:
public class WriteItem
{
public string Name { get; set; }
public object Value { get; set; }
public int ResultCode { get; set; }
public string ErrorMessage { get; set;}
}
我需要处理每个项目并设置其 ResultCode
和 ErrorMessage
属性,我想定义一个类似于此的方法:
public void ProcessItems(WriteItemCollection items)
{
foreach(var item in items)
{
// Process each item and set its result.
}
}
每个项目的处理由另一个class完成。
这是最好的方法吗?
还是让自定义结果 class 的方法 return 成为 collection 更好?
你写的会起作用的。在集合中迭代时,您可以修改对象属性而不会产生副作用。
我不会return一个新的集合,除非你需要保持原始集合的副本不变。
两种选择各有优缺点。两者都是"fine",因为它们没有任何问题,而且它们在 C# 中很常用。
选项 1 的一大优点是简单易行。您甚至可以保留对 WriteItem
实例的引用并在处理后检查其状态。
选项 2 具有更清晰的关注点分离:在选项 1 中,您需要在 WriteItem
class 中添加注释以定义哪些是 "input" 哪些是 "output" 属性。选项 2 不需要。此外,选项 2 允许您使 WriteItem
和 ProcessingResult
不可变,这是一个不错的 属性.
选项 2 也更具可扩展性:如果你想处理除 WriteItem
s 以外的东西(使用相同的 return 选项),你可以定义一个 class
class ProcessingResult<T>
{
public T Item { get; set; }
public int ResultCode { get; set; }
public string ErrorMessage { get; set; }
}
并将其用作 ProcessingResult<WriteItem>
以及 ProcessingResult<SomeOtherItem>
。
我认为这一切都归结为可读性。
当你调用 ProcessItems 时,是否很明显集合发生了变化?如果你这样调用方法:
var items = GetItemsFromSomewhere();
ProcessItems(items);
与这样称呼:
var items = GetItemsFromSomewhere();
items = ProcessItems(items);
或简单地更改您的方法名称:
var items = GetItemsFromSomewhere();
items = UpdateItemStatuses(items);
这个问题在我的书中最终没有正确答案。您应该做适合您的应用程序的事情。并考虑:如果另一个开发人员正在查看这段代码怎么办?他能否推测这里发生了什么,或者他是否必须深入研究 ProcessItems 函数才能了解应用程序的要点。
最好return一个新的结果class。
为什么?
正如其他人所说,您正在修改集合,但不是很清楚。但对我来说这不是主要原因。您可以拥有修改对象的进程。
对我来说,这是因为您必须向 WriteItem 对象添加额外的属性才能支持处理器。这实际上在模型和处理器之间创建了一个不应该存在的强耦合。
考虑一下您有另一种方法 ProcessItems_ForSomeOtherPurpose(List<WriteItem> items)
您是否扩展了 ResultCode
int 以获得更有意义的值?你再添加一个 属性 ResultCode_ForSomeOtherPurpose
吗?如果您需要使用多个处理器多次处理同一个项目怎么办?
我会给你的模型一个 ID。然后你可以针对它记录多个进程
例如。
项目 1 - 已加载
项目 1 - 取货失败!
项目 1 - 已选择
项目 1 - 已交付