How do I preset a variable in a LINQ expression?
I am creating an array of objects based on data strings as shown below. While working, it bothers me a little that I am performing as assignment to multiple fields by pulling the same value from a cell in a row. Usually this thing was pre-prepared before the loop and then just sets a few times , but here, I am not getting the value until inside the actual iteration. p>
return table.Rows.Cast<DataRow>()
.Select(row => new Beep
{
Uno = HeavyComputation(row["ID"]),
Duo = HeavyComputation(row["ID"])
}).ToList();
Can this be considered better? Something like (just dreaming here) so?
return table.Rows.Cast<DataRow>()
.Preset("int preComputed = HeavyComputation(row['ID'])"
.Select(row => new Beep
{
Uno = preComputed,
Duo = preComputed
}).ToList();
Note that the actual example is a little more complex and the above code is a minimal example of the problem. I do understand that Uno and Duo are redundant here. :)
source to share
You can do this instead:
return table.Rows.Cast<DataRow>()
.Select(row => {
long preComputed = HeavyComputation(row["ID"]);
return new Beep
{
Uno = preComputed,
Duo = preComputed
};
});
In this case, the parameter Select
is Func<DataRow, Beep>
. Since a Func<>
is just a delegate, you can pass an anonymous method Select
like in the above example. You can also do this:
public Beep TransformToBeep(DataRow dr)
{
//Do a lot of work here
return new Beep { ... };
}
And then in yours Select
just write:
return table.Rows.Cast<DataRow>().Select(TransformToBeep).ToList();
source to share
In your query expression, you can use let
for this:
return from DataRow row in table.Rows
let preComputed = HeavyComputation(row["ID"])
select new Beep
{
// Use row and preComputed here
};
To have the same effect in an unquery expression, you can use multiple calls Select
:
return table.Rows.Cast<DataRow>()
.Select(row => new { row, preComputed = HeavyComputation(row["ID"]) })
// Other stuff here if you want
.Select(pair => new Beep {
Uno = pair.preComputed,
Duo = pair.preComputed,
Trio = pair.Row[...]
});
If you only need the preComputed
final one Select
, you can simply use:
return table.Rows.Cast<DataRow>()
.Select(row => HeavyComputation(row["ID"]))
.Select(preComputed => new Beep {
Uno = preComputed,
Duo = preComputed
});
And if you're happy to have a lambdas expression (instead of a lambdas expression), you can use Klaus's approach, of course. Be aware that this won't work for things like LINQ to SQL, although it only works with Enumerable
, and the lambdas statement cannot be converted to expression trees.
source to share