我写了这个:
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;
}
}
}
然后用这个去测试它:
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);
}
第一次使用Inspect()
效果很好。第二个,注释掉,不会编译。的回报OrderBy
是IOrderedEnumerable
。我IOrderedEnumerable
原以为是 IEnumerable
-a,但是,我用拳头打滚,我试过:
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;
}
}
但这也不会编译。我被告知我不能有迭代器块,因为 System.Linq.IOrderedEnumberable 不是迭代器接口类型。
我错过了什么?我不明白为什么人们不想像处理原始集合一样迭代有序集合。
(使用 Mono 2.10.8.1,它实际上是 C# 4.0,和 MonoDevelop 2.8.6.3)
更新:
正如 joshgo 好心指出的那样,我可以采用 的输入参数IOrderedEnumerable
,它确实起到了 IEnumerable
-a 的作用。但是要迭代我必须返回IEnumerable
,而我原来的错误是由ThenBy
,坚持给定的IOrderedEnumerable
。也很合理。但是这里有办法满足ThenBy
吗?
更新2:
在玩过两个答案中的代码之后(这两个答案都非常有帮助),我终于明白为什么我不能使用带有 IOrderedEnumerable 返回的 yield:没有意义,因为这些值必须完全可用才能执行种类。因此,与其使用带有 yield 的循环,不如使用循环打印出所有项目,然后在最后只返回一次 source 。