私はこれを書いた:
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()
動作します。コメントアウトされた2つ目は、コンパイルされません。の戻りはOrderBy
ですIOrderedEnumerable
。私はそう思っていたでしょうIOrderedEnumerable
- IEnumerable
しかし、パンチで転がして、私は試しました:
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はイテレーターインターフェイスタイプではないため、イテレーターブロックを使用できないと言われます。
私は何が欠けていますか?生のコレクションと同じように、順序付けられたコレクションを繰り返し処理したくない理由がわかりません。
(事実上C#4.0であるMono 2.10.8.1、およびMonoDevelop 2.8.6.3を使用)
アップデート:
joshgoが親切に指摘したように、私はの入力パラメーターを取ることができますIOrderedEnumerable
、それは確かに-aとして機能し IEnumerable
ます。しかし、繰り返すには、を返す必要があります。元のエラーは、が与えられていることを主張するIEnumerable
によって引き起こされました。非常に合理的でもあります。しかし、ここで満足する方法はありますか?ThenBy
IOrderedEnumerable
ThenBy
UPDATE2:
両方の回答(どちらも非常に役に立ちました)のコードで遊んだ後、IOrderedEnumerableリターンでyieldを使用できない理由を最終的に理解しました:値を実行するには値が完全に利用可能である必要があるため、意味がありません選別。したがって、yieldを含むループの代わりに、ループを使用してすべてのアイテムを印刷し、最後に1回だけソースを返すこともできます。