I have the working foreach as follows.
List<Thing> things = new List<Thing>();
foreach (Original original in originals)
things.Add(new Thing(orignal));
Then, I got smart and LINQified it into the following, still working code.
IEnumerable<Thing> things = originals.Select(origo => new Thing(origo));
Feeling really proud of decimating the number of lines as well and LINQing myself to more clear code I realized that there's also the requirement to update the process table. It's imperative that the update occurs simultanously as we proceed through the transformation. So, with my tail between my legs and feels much less pride, I went back to the original code and added the notification method.
List<Thing> things = new List<Thing>();
foreach (Original original in originals)
{
things.Add(new Thing(orignal));
DoTell();
}
My question is if it's possible to keep the LINQie syntax and still be able to incorporate the teller somehow. I'm not hopeful that the code will look nice nor be more readable that way (although, it'd be awesome if it was). However, now it's a matter of academic curiosity and pure stubborness - I'd like to know if it can be done at all.
There is a really ugly way to do this. It is purely academic.
IEnumerable<Thing> things = originals.Select(origo => {DoTell(); return new Thing(origo)});
You will update your table and return new Thing
in Select
. Select won't fail because you are using brackets in it and tell that you are returning only new Thing
not result of DoTell()
I suggest you to go with foreach
because it will really look cleaner in the end. Using LINQ everywhere is not a solution for cleaner/clearer code.
EDIT:
if you still want to go with LINQ, you can do even uglier version of it (one-liner):
var things = things.Select(x => new { o = new Thing(), b = DoTell()}).Select(x=>x.o);
This approach is pure evil. However it works without return statement :)
This shall work, using original Select Syntax
IEnumerable<Thing> things = originals.Select(origo =>
{
DoTell();
return new Thing(origo);
});
In case DoTell()
needs to be a post call and it needs to use the new Thing
created for some internal usage, which is not apparent in this code, then do the following:
IEnumerable<Thing> things = originals.Select(origo =>
{
var thing = new Thing(origo);
DoTell();
return thing;
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With