I have code that is building up a collection of objects. I'm trying to reduce the number of .ToList()
calls I make, so I'm trying to keep it as IEnumerable<T>
for as long as possible.
I have it almost finished except for two properties which need to be set to a value which is passed into the calling method:
private IEnumerable<X> BuildCollection(int setMe){
IEnumerable<Y> fromService = CallService();
IEnumerable<X> mapped = Map(fromService);
IEnumerable<X> filteredBySomething = FilterBySomething(mapped);
IEnumerable<X> sorted = filteredBySomething
.OrderBy(x=>x.Property1)
.ThenBy(x=>x.Property2);
// Here's the problem: return "sorted", but with each "Property3"
// and "Property4" set to "setMe". I don't want to do:
var sortedList = sorted.ToList();
sortedList.ForEach(s=>
{
s.Property3 = setMe;
s.Property4 = setMe;
};
return sortedList;
}
If one could use sort of a wildcard in a select
, then I could do something like:
return from f in filteredBySomething
order by f.Property1, f.Property2
select new {
f.*,
f.Property3 = setMe,
f.Property4 = setMe
};
That is, I would like to stream back the sorted objects, but with Property3 and Property4 set to the passed-in value.
Is there an elegant way to do this?
P.S. I don't think it matters, but the collection will eventually be sent to an ASP.NET view as a viewmodel. Clearly, .ToList()
may have to be called before the View gets it, but I'd like that to be the only time.
P.P.S. I should have said that type X
has about 30 properties! using
select new {
x.Property1,
x.Property2,
Property3 = setMe,
Property4 = setme,
// ...
}
would not be useful, as the ...
would be another 26 properties.
Here's what I wound up with:
private IEnumerable<X> BuildCollection(int setMe){
IEnumerable<Y> fromService = CallService();
IEnumerable<X> mapped = Map(fromService);
IEnumerable<X> filteredBySomething = FilterBySomething(mapped);
IEnumerable<X> sorted = filteredBySomething
.OrderBy(x=>x.Property1)
.ThenBy(x=>x.Property2);
// The method already returns IEnumerable<X> - make it an iterator
foreach (var x in sorted)
{
x.Property3 = setMe;
x.Property4 = setMe;
yield return x;
}
}