0

私はリアクティブフレームワークを見始めました。とても素敵なもの。しかし、コード サンプルを見ていると、混乱してしまいました。linq 構文は IQueryable で機能します。linq は IEnumerable でのみ動作すると思いました。C# コンパイラは何に基づいて拡張メソッドの変換を行っていますか? 特定のインターフェースを持つ一連のメソッドが必要ですか?

4

1 に答える 1

5

そうではありません。単なる構文変換です。たとえば、コンパイラは次のように変換します。

var query = from item in source
            select item.Property;

の中へ

var query = source.Select(item => item.Property);

Selectメソッドについて何も知らずにそれを行います。翻訳を行うだけで、翻訳されたコードをコンパイルしようとします。

すべての翻訳は、C# 4 仕様のセクション 7.16 で慎重に文書化されています (もちろん、以前の版の同等の文書も含まれています)。

Rx の場合、 と の拡張機能を呼び出しIObservable<T>ますIQbservable<T>。Parallel Extensions の場合、 で拡張メソッドを呼び出しますParallelQuery<T>

あなたはそれでいくつかの狂ったことをすることができます.いくつかの例を示すブログ投稿があります. ここに別の奇妙なものがあります:

using System;
using System.Linq;

namespace CornerCases
{
    class WeirdQueryExpression
    {
        static WeirdQueryExpression Where(Func<int, int> projection)
        {
            return new WeirdQueryExpression { Select = ignored => "result!" };
        }

        Func<Func<string, bool>, string> Select { get; set; }

        static void Main()
        {
            string query = from x in WeirdQueryExpression
                           where x * 3
                           select x.Length > 10;

            Console.WriteLine(query);
        }
    }
}

クエリは次のように変換されます。

WeirdQueryExpression.Where(x => x * 3)
                    .Select(x => x.Length > 10);

... これは、 を返す静的メソッドの呼び出しであり、その後にを返すプロパティにWeirdQueryExpressionアクセスします。次に、そのデリゲートを呼び出し(別のデリゲートを渡します)、結果を に代入します。WhereFunc<Func<string, bool>, string>query

ファンキーでしょ?

于 2010-06-21T19:54:13.120 に答える