简化双foreach指令

本文关键字:指令 foreach | 更新日期: 2023-09-27 18:17:14

我需要浏览一个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();

我想知道形状中包含"文本框"的元素有多少

简化双foreach指令

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

使用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"));

请注意,您的版本是低效的,因为它创建了一个列表和KeyValuePair s不必要,因为您只想计算符合某些条件的形状的数量。除此之外,嵌套的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;
        }
    }
}