【问题标题】:Am I enumerating my IEnumerable<T> n times?我是否在枚举我的 IEnumerable<T> n 次?
【发布时间】:2020-08-21 15:38:53
【问题描述】:

相当对 C# 中的 LINQ 感到满意,但我不知道我的 foreach 循环是否导致过多枚举。

假设运行以下代码sn-p,

var listOfStuff = new List<CustomObject>
{
    new CustomObject { Id = 1, Cost = 20M },
    new CustomObject { Id = 2, Cost = 11M },
    new CustomObject { Id = 3, Cost = 3.75M },
    new CustomObject { Id = 4, Cost = 50.99M }
};
var newObjects = listOfStuff.Select(thing =>
    new AnotherObject { Id = x.ID, NegaCost = decimal.Negate(x.Cost) });

foreach (var i in n) // a list of objects with a length of n
{
   var match = newObjects.Where(PreDefinedPredicate);
   i.DoSomethingWith(match);
}

是一个新的AnotherObject 实例被创建了 n 次还是我误解了多重枚举的概念?

【问题讨论】:

  • 假设 DoSomethingWith 迭代您的查询,然后在通过 foreach 的每个循环上是肯定的,您将创建一组新的 AnotherObjects 进行过滤。为避免这种情况,您可以在输入foreach 之前执行ToList
  • 是的,您正在多次实例化该对象,但仅在您枚举集合时,因此如果您需要对其进行水合,请使用ToList - 啊,被打败了:(
  • 它在i 对象上执行的另一种方法中被枚举,但我假设同样会发生。谢谢!
  • 这很容易测试吗?
  • 可能,但在我的辩护中,我是新来的

标签: c# linq enumeration deferred-execution


【解决方案1】:

这取决于您如何处理 i.DoSomethingWith 中的 match,但如果您在其中迭代它,那么可以。

您可以随时检查您的假设是否引入了一些副作用,例如 Console.WriteLine:

var newObjects = listOfStuff.Select(x =>
    {
         Console.WriteLine($"Here with id: {x.Id}"); // SIDEEFFECT
         return new AnotherObject { Id = x.ID, NegaCost = decimal.Negate(x.Cost) };
    });

foreach (var i in n) // a list of objects with a length of n
{
   var match = newObjects.Where(PreDefinedPredicate);
   i.DoSomethingWith(match);
}

【讨论】:

    猜你喜欢
    • 2012-05-28
    • 2017-05-06
    • 2017-01-09
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多