I have a List/IEnumerable of objects and I’d like to perform a calculation on some of them.
e.g.
myList.Where(f=>f.Calculate==true).Calculate();
to update myList, based on the Where clause, so that the required calulcation is performed and the entire list updated as appropriate.
The list contains “lines” where an amount is either in Month1, Month2, Month3…Month12, Year1, Year2, Year3-5 or “Long Term”
Most lines are fixed and always fall into one of these months, but some “lines” are calulcated based upon their “Maturity Date”.
Oh, and just to complicate things! the list (at the moment) is of an anonymous type from a couple of linq queries. I could make it a concrete class if required though, but I’d prefer not to if I can avoid it.
So, I’d like to call a method that works on only the calculated lines, and puts the correct amount into the correct “month”.
I’m not worried about the calculation logic, but rather how to get this into an easily readable method that updates the list without, ideally, returning a new list.
[Is it possible to write a lambda extension method to do both the calculation AND the where – or is this overkill anyway as Where() already exists?]
Personally, if you want to update the list in place, I would just use a simple loop. It will be much simpler to follow and maintain:
This, at least, is much more obvious that it’s going to update. LINQ has the expectation of performing a query, not mutating the data.
If you really want to use LINQ for this, you can – but it will still require a copy if you want to have a
List<T>as your results:This would call your
Calculate()method as needed, and copy the original when not needed. It does require a copy to create a newList<T>, though, as you mentioned that was a requirement (in comments).However, my personal preference would still be to use a loop in this case. I find the intent much more clear – plus, you avoid the unnecessary copy operation.
Edit #2:
Given this comment:
If you really want to use LINQ style syntax, I would recommend just not calling
ToList()on your original queries. If you leave them in their original,IEnumerable<T>form, you can easily do my second option above, but on the original query:This has the advantage of only constructing the list one time, and preventing the copy, as the original sequence will not get evaluated until this operation.