次の方法で共有


式ツリー

式ツリー は、ツリーに似たデータ構造のコードを表します。各ノードは式です。たとえば、メソッド呼び出しや、 x < yなどのバイナリ操作です。

LINQ を使用した場合、 Func 型が API セットの一部であるリッチ ライブラリを使用した経験があります。 (LINQ に慣れていない場合は、LINQ チュートリアル と、この前に ラムダ式 に関する記事を読む必要があります)。式ツリーは、関数である引数とのより豊富な相互作用を提供します。

関数引数は、LINQ クエリを作成するときに、通常はラムダ式を使用して記述します。 一般的な LINQ クエリでは、これらの関数引数はコンパイラによって作成されるデリゲートに変換されます。

式ツリーを使用するコードはすでに記述されています。 Entity Framework の LINQ API は、LINQ クエリ式パターンの引数として式ツリーを受け入れます。 これにより、 Entity Framework では、C# で記述したクエリを、データベース エンジンで実行される SQL に変換できます。 もう 1 つの例として、.NET 用の一般的なモック フレームワークである Moq があります。

より豊富な操作を行う場合は、 式ツリーを使用する必要があります。 式ツリーは、コードを、確認、変更、または実行する構造体として表します。 これらのツールを使用すると、実行時にコードを操作できます。 実行中のアルゴリズムを調べたり、新しい機能を挿入したりするコードを記述します。 より高度なシナリオでは、実行中のアルゴリズムを変更し、別の環境で実行するために C# 式を別の形式に変換します。

式ツリーで表されるコードをコンパイルして実行します。 式ツリーをビルドして実行すると、実行可能コードの動的な変更、さまざまなデータベースでの LINQ クエリの実行、動的クエリの作成が可能になります。 LINQ の式ツリーの詳細については、「式ツリー を使用して動的クエリを作成する方法」を参照してください。

式ツリーは、動的言語ランタイム (DLR) でも使用され、動的言語と .NET 間の相互運用性を提供し、コンパイラ ライターが Microsoft 中間言語 (CIL) ではなく式ツリーを出力できるようにします。 DLR の詳細については、「 動的言語ランタイムの概要」を参照してください。

C# または Visual Basic コンパイラで匿名ラムダ式に基づいて式ツリーを作成することも、 System.Linq.Expressions 名前空間を使用して式ツリーを手動で作成することもできます。

ラムダ式が Expression<TDelegate>型の変数に割り当てられると、コンパイラはラムダ式を表す式ツリーを構築するコードを出力します。

次のコード例では、C# コンパイラでラムダ式 num => num < 5を表す式ツリーを作成する方法を示します。

Expression<Func<int, bool>> lambda = num => num < 5;

コードで式ツリーを作成します。 ツリーを構築するには、各ノードを作成し、ノードをツリー構造にアタッチします。 式 ツリーの構築に関する記事では、式を作成する方法について説明します。

式ツリーは変更できません。 式ツリーを変更する場合は、既存の式ツリーをコピーし、その中のノードを置き換えて、新しい式ツリーを構築する必要があります。 式ツリー ビジターを使用して、既存の式ツリーをトラバースします。 詳細については、 式ツリーの変換に関する記事を参照してください。

式ツリーを作成したら、 式ツリーで表されるコードを実行します

制限事項

C# コンパイラは、式ラムダ (または単一行ラムダ) からのみ式ツリーを生成します。 ステートメントラムダ (または複数行ラムダ) を解析することはできません。 C# のラムダ式の詳細については、「 ラムダ式」を参照してください。

式ツリーにうまく変換されない新しい C# 言語要素がいくつかあります。 式ツリーには、 await 式や async ラムダ式を含めることはできません。 C# 6 以降で追加された機能の多くは、式ツリーで記述されているとおりには表示されません。 代わりに、新しい機能は、可能な場合は同等の以前の構文で式ツリーで公開されます。 その他のコンストラクトは使用できません。 これは、新しい言語機能が導入されたときに、式ツリーを解釈するコードが同じように動作することを意味します。 ただし、これらの制限がある場合でも、式ツリーを使用すると、データ構造として表されるコードの解釈と変更に依存する動的アルゴリズムを作成できます。 これにより、Entity Framework などの豊富なライブラリで、その機能を実現できます。

式ツリーでは、新しい式ノードの種類はサポートされません。 式ツリーを解釈するすべてのライブラリが新しいノードタイプを導入するのは破壊的変更です。 次の一覧には、使用できないほとんどの C# 言語要素が含まれています。