views:

399

answers:

1

Say I have the following code (context narrowed down as to keep the question scope limited)

public static IEnumerable<Color> GetThemColors(){
 var ids = GetThePrimaryIds();
 foreach (int id in ids){
  yield return GetColorById(id);
 }
 ids = GetTheOtherIds();
 foreach (int id in ids){
  yield return GetOtherColorsById(id);
 }
}

I would like to rewrite them to something like this (which off course doesn't compile

public static IEnumerable<Color> GetThemColors(){
 GetThePrimaryIds().Select(id=>yield return GetColorById(id));
 GetTheOtherIds().Select(id=>yield return GetOtherColorsById(id));  
}

The key point being that in my first snippet I have two foreach enumerators yielding, which I don't know how to do in linq without loosing my lazy-loading features.

+7  A: 

You want Concat:

return GetThePrimaryIds().Select(id => GetColorById(id)).Concat(
    GetTheOtherIds().Select(id => GetOtherColorsById(id)));

Also note that you don't need yield return in lambdas.

Pavel Minaev
Thanks, didn't realize the concat was lazy
borisCallens
As far as I know all the methods on Enumerable that return an IEnumerable are lazy.
Joren
True, but I assumed for some reason Concat would return a IList
borisCallens
It should be noted that the call to `GetTheOtherIds()` is _not_ lazy, i.e. it will first call `GetThePrimaryIds()`, then call `GetTheOtherIds()`, then call `Concat()`. However, if the methods themselves are lazy, then it's not a problem.
Pavel Minaev