Reputation: 67340
I'm using the following pattern in C#:
IList<foo> x = y.Select(a => new foo
{
b = Calc1(),
c = Calc2()
}).ToList();
foreach(foo f in x)
{
f.d = b / c;
}
What I would like to do though is:
IList<foo> x = y.Select(a => new foo
{
b = Calc1(),
c = Calc2()
d = b / c;
}).ToList();
So the question is: How can you modify this pattern to allow the assignment of a value that is dependent on other values being calculated during the assignment?
(Somebody will probably point out that d should be a property that does the calculation and return a value. This is a contrived example. Assume that the value of d is calculated using other values in addition to c & b which are not available later.)
Upvotes: 4
Views: 632
Reputation: 110161
You can't re-use initialized properties in an initializer.
I like Erik's technique. If the query expression syntax is a bother, you can use a full-on anonymous method.
List<int> y = new List<int>() { 1, 2, 3, 4 };
var x = y.Select(a =>
{
int b = a + 1;
int c = a + 2;
int d = b / c;
return new { b = b, c = c, d = d };
});
Upvotes: 5
Reputation: 35871
If you expand this to use the full LINQ syntax:
IList<foo> x = (from a in y
let bq = Calc1()
let cq = Calc2()
select new foo {
b = bq,
c = cq,
d = bq / cq
}).ToList();
This will get you what you want.
There was an answer recommending you repeat your method calls (ie, d = Calc1() / Calc2()) - but I would recommend against this, considering it may be possible that Calc1() and Calc2() are expensive operations, and needlessly performing them twice may have performance implications.
Upvotes: 8