嵌套foreach——需要在每一层对对象进行操作

本文关键字:一层 对象 操作 foreach 嵌套 | 更新日期: 2023-09-27 18:05:30

我试图重构一些嵌套的foreach循环,但遇到了一个问题。这是原始代码:

foreach(var doc in customTrackerDocuments)
{
    foreach(var rule in doc.Rules)
    {
        foreach(var eval in rule.Evaluations)
        {
            // Do something with customTrackerDocuments, rules, and evaluations
            // doc, rule, and eval are all available here
        }
    }
}

无可否认,它是干净和直接的,所以也许它应该保持这样。然而,我一直在尝试降低复杂性和提高可读性,所以我尝试这样做:

foreach(var eval in customTrackerDocuments.SelectMany(doc => doc.Rules).SelectMany(rule => rule.Evaluations))
{
    // Do something with customTrackerDocuments, rules, and evaluations
    // doc and rule are NOT available here
}

问题是doc和rule不再可以在循环中使用。有没有一种方法可以让他们使用这种方法?或者我应该使用第一个有三个嵌套循环的选项?

我这里有一个小提琴:https://dotnetfiddle.net/oBMfQC

嵌套foreach——需要在每一层对对象进行操作

它们不可用,因为您只在最终的SelectMany中投影rule.Evaluations。您可以创建一个匿名类型:

foreach(var eval in customTrackerDocuments.SelectMany(doc => doc.Rules, rule => new {doc, rule})
                                          .SelectMany(docrule => docrule.rule.Evaluations, eval => new {docrule.doc, docrule.rule, eval}))
{
    // eval.doc, eval,rule, eval.eval are available here
}

这是更容易读还是更不复杂是有争议的。它当然不会更快或使用更少的内存。