Reputation: 334
I almost don't use "yield" operator (I don't hate it :)). I prefer to use LINQ if it is possible. Anyways, I looked for some post (you can find link below) 10 minutes ago, read it and some idea visited my brain :)
rewrite-this-foreach-yield-to-a-linq-yield
Idea: Probably, it is not very good that I don't use "yield". Probably, it has better performance than LINQ or some other advantage.
Therefore I have next question, what code is more "correct" (yield or LINQ) in example above (in common case)?
P.S. I am interesting for cases when we have possibility to use LINQ instead of "yield".
Upvotes: 4
Views: 4437
Reputation: 113232
Ignoring for the moment the way that Linq can be processed by other query providers (e.g. against a database), in the example you link to we have two different approaches:
Enumerable.Concat
method.Well, what is Enumerable.Concat
? Since we're ignoring cases like Linq2SQL (which would likely turn concat into a UNION ALL
) what we care about here is the Linq2Objects implementation.
Now, there's more than one way to skin a concat, but the Mono source (for example) ends up calling a check and then into:
static IEnumerable<TSource> CreateConcatIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second)
{
foreach (TSource element in first)
yield return element;
foreach (TSource element in second)
yield return element;
}
In other words, the LINQ approach is the yield
approach.
Or if not, it might be something very similar. We could (if we liked typing more) implement it as the construction of an implementation of IEnumerator<TSource>
, but yield
saves us the hassle.
In all, LINQ is a bunch of handy tools that work well together. When they're the tool that works well, use them. When another tool works better, use it. When a LINQ-like tool would be nice, but it's not included in what you've got, write it yourself (just like we could do all the Linq2Objects stuff before Linq, which wasn't there for us in .NET2.0).
Upvotes: 1
Reputation: 110071
public static IEnumerable<Color> GetThemColors(){
GetThePrimaryIds().Select(id=>yield return GetColorById(id));
GetTheOtherIds().Select(id=>yield return GetOtherColorsById(id));
}
This code doesn't work. Select is lazy and those collections are not enumerated.
Upvotes: 2
Reputation: 1499860
I think it's clearer to use LINQ in that case, personally. It's operating at a higher level than "call this method, yield this result" - it describes the overall results.
Iterator blocks are very useful for implementing LINQ though - either the existing operators, or adding your own. It's worth knowing about them, but I wouldn't worry about the fact that you're not using them much - that's not a sign of poor code or anything like that.
Upvotes: 8