foreach(... in ...)或.ForEach();就是那个问题

时间:2010-02-09 16:13:26

标签: c# lambda foreach readability

  

可能重复:
  C# foreach vs functional each

这是关于可读性编码的问题。

我有一个XDocument和一个List<string>元素的名称,这些元素包含我需要屏蔽的敏感信息(在本例中用下划线替换)。

XDocument xDoc;
List<string> propertiesToMask;

这可以用两种方式编写,使用传统的foreach循环,或使用lamba语法的.ForEach方法。

foreach (string propertyToMask in propertiesToMask)
{
    foreach (XElement element in xDoc.Descendants(propertyToMask))
    {
        element.SetValue(new string('_', element.Value.Length));
    }
}

propertiesToMask
    .ForEach(propertyToMask => xDoc.Descendants(propertyToMask).ToList()
        .ForEach(element => element.SetValue(new string('_', element.Value.Length))));

您认为哪种方法最具可读性?为什么?如果你更喜欢第二个例子,你会如何呈现它以获得最大的可读性?

6 个答案:

答案 0 :(得分:14)

Eric Lippert有一个good entry about this on his blog。总而言之,ForEach完成的任务是产生副作用,这可能不是C#中编程功能样式的理想选择。

答案 1 :(得分:14)

foreach (string propertyToMask in propertiesToMask)
{
    foreach (XElement element in xDoc.Descendants(propertyToMask))
    {
        element.SetValue(new string('_', element.Value.Length));
    }
}

因为间距使得扫描非常简单。第二个是混乱的,我必须实际阅读它。

答案 2 :(得分:4)

我非常喜欢第一个,原因有三个。

首先,它更有效率(在第二种情况下,你有额外的ToList()调用)。

其次,在我看来,它更具可读性。

最后,我建议阅读Eric Lippert's blog post on this subject.有一些哲学原因可以避免List<T>.ForEach,因为它的全部目的是引起副作用,即使它具有功能风格。

答案 3 :(得分:4)

传统方式具有可轻松调试的巨大优势。但在这种情况下,我个人更喜欢ForEach()方法。在我看来,用流利的代码编写代码很难调试的情况是可用工具的缺陷,而不是编码风格。根据我个人的经验,这种方法的错误率非常低,因此它不是一个大问题。

我会写一些扩展方法,产生以下代码。

propertiesToMask
   .SelectMany(property => document.Descendants(property))
   .ForEach(element => element.MaskValue());

答案 4 :(得分:1)

第一个可以在调试器运行时更​​改,Visual Studio允许您继续调试。更改.ForEach变体后,您必须重新启动调试会话并重新编译,因为它包含lambda表达式(VS 2008)

答案 5 :(得分:0)

这是一个非常主观的答案:

我真的不同意不喜欢的哲学推理。每个人。也许这是我缺乏计算机科学背景,我不知道。

对我来说,第二组代码更易于阅读,而且看起来更不容易。正如其他人所提到的,ToList()有点不幸,但它对我来说仍然看起来更好。

我更喜欢DanielBrückner的解决方案。它似乎比其他任何提出的解决方案都要好。