0

I am fairly comfortable with LINQ in c#, but am lost on whether or not my foreach loop is causing excessive enumeration.

Assuming the following code snippet is run,

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);
}

is a new AnotherObject instance being created n times or am i misunderstanding the concept of multiple enumerations?

BakeryD
  • 3
  • 3
  • 1
    Assuming that `DoSomethingWith` iterates your query then yes on each loop through the `foreach` you will creat a new set of `AnotherObject`s to filter. To avoid that you could do `ToList` before entering the `foreach`. – juharr May 06 '20 at 15:37
  • Yes, you are instantiating the object multiple times but only when you enumerate the collection so if you need to hydrate it use `ToList` - ah beaten to the punch :( – Charleh May 06 '20 at 15:38
  • It's enumerated in another method performed on the `i` object, but i'm assuming the same will occur. Thanks! – BakeryD May 06 '20 at 16:41
  • Surely this is easy enough to test? – Rufus L May 06 '20 at 17:15
  • Probably, but in my defense i'm new here – BakeryD May 06 '20 at 17:54

1 Answers1

3

It depends what do you do with match in i.DoSomethingWith, but if you are iterating it in there, then yes.

You can always check you assumption introducing some side-effect like 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);
}
Guru Stron
  • 102,774
  • 10
  • 95
  • 132