简化 double foreach 指令

Simplify double foreach instruction

我需要浏览一个 word 文档并检索一些文本框以便对其进行修改。

但是我之前需要统计一下,我觉得我写的真的很低效

我想知道是否可以简化以下内容:

foreach (Microsoft.Office.Interop.Word.HeaderFooter OHeader in documentOld.Sections[1].Headers)
{
    foreach (Microsoft.Office.Interop.Word.Shape shape in OHeader.Shapes)
    {
        if (shape.Name.Contains("Text Box"))
        {
            listTextBox.Add(new KeyValuePair<string, string>(shape.Name.ToString(), shape.TextFrame.TextRange.Text.ToString()));
        }
    }
}

int count = listTextBox.Count();

我想知道 Shapes 中有多少包含 "Text Box" 的元素。

我看到有两种方法可以做到这一点。

使用 LINQ 语法:

var count = (
  from OHeader in documentOld.Sections[1].Headers
  from shape in OHeader.Shapes
  where shape.Name.Contains("Text Box")).Count();

或者,使用 IEnumerable 扩展方法:

var count = documentOld.Sections[1].Headers
              .SelectMany(h => h.Shapes)
              .Count(s => s.Name.Contains("Text Box"));

请注意,您的版本效率低下,因为它会不必要地创建一个列表和 KeyValuePairs,因为您只想计算符合某些条件的形状的数量。除此之外,嵌套的 foreach 块对于性能来说很好,但与 LINQ 等价物相比可能缺乏可读性。

另外,请注意我没有测试上面的代码。

通过使用 foreach 循环来保持代码不变,您仍然需要做的就是在循环之前设置 count 变量,并在每次找到匹配项时递增它。

int count = 0;
foreach (Microsoft.Office.Interop.Word.HeaderFooter OHeader in documentOld.Sections[1].Headers)
{
    foreach (Microsoft.Office.Interop.Word.Shape shape in OHeader.Shapes)
    {
        if (shape.Name.Contains("Text Box"))
        {
            ++count;
        }
    }
}