【问题标题】:Does using a LINQ statement in a foreach re-evaluate the statement on each iteration在 foreach 中使用 LINQ 语句是否会在每次迭代时重新评估语句
【发布时间】:2015-07-16 15:05:09
【问题描述】:

所以我想知道的是,在我的foreach 循环中使用LINQ where 子句是否意味着在每次迭代时它都会重新评估我的LINQ where 子句。例如:

var MyId = 1;
foreach (var thing in ListOfThings.Where(x => x.ID == MyId))
{ 
  //do Something
}

还是写得更好:

var MyId = 1;

var myList = ListOfThings.Where(x => x.ID == MyId);
foreach (var thing in myList)
{ 
  //do Something
}

或者它们的工作方式完全相同?

【问题讨论】:

  • 最后一个问题:是的
  • 同样的 :-) 任何方式 Where 返回迭代器,所以只执行一次
  • 拿个IL反汇编器,反汇编两个代码,看看有没有区别
  • @IssaJaber 两者的 IL 永远不会相同......他的问题是它们是否执行相同的功能......他们所做的。
  • @DavidG 好主意,虽然我必须补充一点,TestFunc 将为列表中的每个项目执行,因此真正的测试是TestFunc 执行的次数与List.Count 相同

标签: c# linq foreach


【解决方案1】:

foreach (var thing in myExpression) 调用 myExpression.GetEnumeratorMoveNexts 直到它返回 false。所以你的两个sn-ps是一样的。

(顺便说一句,GetEnumeratorIEnumerable 上的一个方法,但 myExpression 不一定是 IEnumerable;只是一个带有 GetEnumerator 方法的东西。

【讨论】:

    【解决方案2】:

    这个样本应该会给你所有你想要的答案:

    代码

    using System;
    using System.Linq;
    
    public class Test
    {
        public static void Main()
        {
            // Create sequence of integers from 0 to 10
            var sequence = Enumerable.Range(0, 10).Where(p => 
            { 
                // In each 'where' clause, print the current item.
                // This shows us when the clause is executed
                Console.WriteLine(p); 
    
                // Make sure every value is selected
                return true;
            });
    
            foreach(var item in sequence)
            {
                // Print a marker to show us when the loop body is executing.
                // This helps us see if the 'where' clauses are evaluated 
                // before the loop starts or during the loop
                Console.WriteLine("Loop body exectuting.");
            }
        }
    }
    

    输出

    0
    Loop body exectuting.
    1
    Loop body exectuting.
    2
    Loop body exectuting.
    3
    Loop body exectuting.
    4
    Loop body exectuting.
    5
    Loop body exectuting.
    6
    Loop body exectuting.
    7
    Loop body exectuting.
    8
    Loop body exectuting.
    9
    Loop body exectuting.
    

    结论

    Where 子句在每次循环迭代开始时针对当前元素计算一次。

    【讨论】:

      【解决方案3】:

      所以从 cmets 中我发现 foreach 循环不会在每次迭代时重新评估我的 LINQ where

      MSDN Enumerable.Where我可以看到这个方法返回一个IEnumerable

      返回值类型:System.Collections.Generic.IEnumerable An IEnumerable 包含来自输​​入序列的元素 满足条件。

      然后在 foreach 循环中迭代

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-20
        • 2012-08-17
        • 1970-01-01
        • 1970-01-01
        • 2021-04-01
        • 2010-10-04
        • 2012-12-23
        相关资源
        最近更新 更多