I wrote this:
using System;using System.Linq;
static class MyExtensions
{
public static IEnumerable<T> Inspect<T> (this IEnumerable<T> source)
{
Console.WriteLine ("In Inspect");
//return source; //Works, but does nothing
foreach(T item in source){
Console.WriteLine(item);
yield return item;
}
}
}
Then went to test it with this:
var collection = Enumerable.Range(-5, 11)
.Select(x => new { Original = x, Square = x * x })
.Inspect()
.OrderBy(x => x.Square)
//.Inspect()
.ThenBy(x => x.Original)
;
foreach (var element in collection)
{
Console.WriteLine(element);
}
The first use of Inspect()
works fine. The second one, commented out, won't compile. The return of OrderBy
is IOrderedEnumerable
. I'd have thought IOrderedEnumerable
is-a IEnumerable
but, rolling with the punches, I tried:
public static IOrderedEnumerable<T> Inspect<T> (this IOrderedEnumerable<T> source)
{
Console.WriteLine ("In Inspect (ordered)");
foreach(T item in source){
Console.WriteLine(item);
yield return item;
}
}
But this won't compile either. I get told I cannot have an iterator block because System.Linq.IOrderedEnumberable is not an iterator interface type.
What am I missing? I cannot see why people wouldn't want to iterate over an ordered collection the same way they do with the raw collection.
(Using Mono 2.10.8.1, which is effectively C# 4.0, and MonoDevelop 2.8.6.3)
UPDATE:
As joshgo kindly pointed out, I can take an input parameter of IOrderedEnumerable
, it does indeed act as-a IEnumerable
. But to iterate I must return IEnumerable
, and my original error was caused by ThenBy
, which insists on being given IOrderedEnumerable
. Very reasonable too. But is there a way to satisfy ThenBy
here?
UPDATE2:
After playing with the code in both answers (both of which were very helpful), I finally understood why I can't use yield with an IOrderedEnumerable return: there is no point, because the values have to be fully available in order to do the sort. So instead of a loop with yield in it, I may as well use a loop to print out all items, then just return source once at the end.