【问题标题】:How to reduce multiple nested foreach blocks如何减少多个嵌套的foreach块
【发布时间】:2017-10-13 21:34:16
【问题描述】:

我有以下场景:

var Ids = object1.GetIds(); // returns IEnumerable<int>
foreach (var id in Ids)
{
    foreach (var relatedObject in object1.GetRelatedObjects(id))
    {
    // Do Something with related object
    }
}

在这种情况下,我想摆脱第一个 foreach 并将这个逻辑简化为单个 foreach。我怎样才能做到这一点?

LINQ 表达式是否应该有一些类似的方法?

【问题讨论】:

  • 如果你使用的是EF,应该有一些像object1.RelatedObjects这样的属性

标签: c# .net linq foreach


【解决方案1】:

当两个循环之间没有任何内容时,在嵌套循环之前或之后,您可以使用SelectMany 将两个循环“压平”为一个:

foreach (var relatedObject in Ids.SelectMany(object1.GetRelatedObjects)) {
    ...
}

此循环与您拥有的循环之间的一个主要区别是id 不再在范围内。假设 relatedObject 公开了一个公共 Id 属性,这在您的情况下应该不是问题,因为您可以将 id 提取回来

var id = relatedObject.Id;

【讨论】:

  • 正是,正是我想要的。谢谢
  • 我认为该语句也可以简化为以下内容:foreach(var relatedObject in Ids.SelectMany(object.GetRelatedObjects){ ... }
  • @stackerflow 你说得对,最好用方法组语法重写。
  • @Abion47 当您希望两个循环在扁平层次结构上表现得像一个循环时,使用一个循环编写代码可以通过更接近您实际想要表达的内容来提高可读性。比较“处理与列表中的 ID 相关的对象”与“从列表中获取 ID,找到它们的相关对象并处理它们”。消除中间步骤使逻辑更容易遵循;同样的事情发生在代码中。
  • var RelatedObjects = object1.GetIds().SelectMany(object1.GetRelatedObjects); foreach (var relatedObject in RelatedObjects) { ... }
【解决方案2】:

我个人喜欢充分利用foreach 循环的可选大括号/块。

您无法降低复杂性。但是你可以让它看起来更好看

IEnumerable<int> Ids = object1.GetIds()

foreach (var id in Ids)
foreach (var relatedObject in object1.GetRelatedObjects(id))
{
     DoSomething(relatedObject);
}

【讨论】:

  • 根据我的经验,Visual Studio 有时不喜欢这种同行的嵌套块,但是当它决定采用它时,它看起来很流畅。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-21
  • 1970-01-01
  • 1970-01-01
  • 2019-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多