Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rewrite this foreach yield to a linq yield?

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.

like image 995
Boris Callens Avatar asked Dec 01 '09 09:12

Boris Callens


People also ask

How do you foreach in LINQ?

Convert a foreach loop to LINQ refactoringPlace your cursor in the foreach keyword. Press Ctrl+. to trigger the Quick Actions and Refactorings menu. Select Convert to LINQ or Convert to Linq (call form).

Does LINQ use yield?

It's more the other way around, that linq is functional in style, so it uses yield.

Which is better foreach or LINQ?

Most of the times, LINQ will be a bit slower because it introduces overhead. Do not use LINQ if you care much about performance. Use LINQ because you want shorter better readable and maintainable code. So your experience is that LINQ is faster and makes code harder to read and to maintain?

How do you yield in C#?

To use "yield return", you just need to create a method with a return type that is an IEnumerable (arrays and collections in. Net implements IEnumerable interface) with a loop and use "yield return" to return a value to set in the loop body.


1 Answers

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.

like image 145
Pavel Minaev Avatar answered Oct 10 '22 14:10

Pavel Minaev