Linq の核の 1 つとも言える式ツリー。なぜそれが Linq の核の 1 つなのか?式ツリーにより、C# は単に IL にコンパイルされなくなるため、C# を通じて式ツリーを生成し、その結果を中間形式として使用し、それをターゲット プラットフォーム上のネイティブ言語に変換できます。 SQLなど。これは、一般的に使用される Linq to sql が SQL を生成する方法です。
式ツリーは、.NET 3.5 の後に導入されました。これは、LINQ で動的クエリを構築するために使用される強力で柔軟なツールです。
まず、Expression クラスの API インターフェイスを見てみましょう:
namespace System.Linq.Expressions { // // 摘要: // 以表达式目录树的形式将强类型 lambda 表达式表示为数据结构。此类不能被继承。 // // 类型参数: // TDelegate: // System.Linq.Expressions.Expression`1 表示的委托的类型。 public sealed class Expression<TDelegate> : LambdaExpression { // // 摘要: // 将表达式树描述的 lambda 表达式编译为可执行代码,并生成表示该 lambda 表达式的委托。 // // 返回结果: // 一个 TDelegate 类型的委托,它表示由 System.Linq.Expressions.Expression`1 描述的已编译的 lambda 表达式。 public TDelegate Compile(); // // 摘要: // 生成表示 lambda 表达式的委托。 // // 参数: // debugInfoGenerator: // 编译器用于标记序列点并批注局部变量的调试信息生成器。 // // 返回结果: // 包含 lambda 的已编译版本的委托。 public TDelegate Compile(DebugInfoGenerator debugInfoGenerator); // // 摘要: // 创建一个与此表达式类似的新表达式,但使用所提供的子级。如果所有子级都相同,则将返回此表达式。 // // 参数: // body: // 结果的 System.Linq.Expressions.LambdaExpression.Body 属性。 // // parameters: // 结果的 System.Linq.Expressions.LambdaExpression.Parameters 属性。 // // 返回结果: // 此表达式(如果未更改任何子级),或带有更新的子级的表达式。 public Expression<TDelegate> Update(Expression body, IEnumerable<ParameterExpression> parameters); protected internal override Expression Accept(ExpressionVisitor visitor); } }
式ツリーの構文は次のとおりです:
Expressioncd1dbc6e985823aa17cbff7e6d77957f> = (param) => lamdaexpresion;
例:
Expression<Func<int, int, int>> expr = (x, y) => x+y;
上記のコードを実行しますこれを VS デバッグ シミュレーションの式ツリーの下に表示します:
式ツリーは主に次の 4 つの部分で構成されていることがわかります:
1. 本体の主要部分
2. パラメータ パラメータ 部分
3. NodeType ノードタイプ
4. ラムダ式のタイプ
上記のコードでは、本体は x+y、パラメータは (x, y)、NodeType は Lambda 式です。戻り値は int です
主要部分は式にすることができますが、ステートメントを含めることはできません。例: デリゲートを定義し、ラムダ式は次のように書くことができます
Func<int, int, int> func = (x, y) => x + y;
または次のように書くことができます:
Func<int, int, int> func = (x, y) => { return x + y; };
ただし、式ツリーでは最初のもののみを使用できます。 2 番目の方法を使用する場合、コンパイル レポートの作成エラー: ステートメント本体を含むラムダ式を式ツリーに変換できません。
上記の記述方法に加えて、式ツリーは次のように記述することもできます:
ParameterExpression pex1 = Expression.Parameter(typeof(int), "x");//第一个参数 ParameterExpression pex2 = Expression.Parameter(typeof(int), "y");//第二个参数 BinaryExpression bexp = Expression.Add(pex1, pex2);//加法 var lambdaExp = Expression.Lambda<Func<int, int, int>>(bexp, new ParameterExpression[] {pex1,pex2 });
VS デバッグ モードでは、2 つの記述方法によって生成された式ツリーが同じ
式を置き換えます。ツリーはデリゲートにコンパイルされます
LambdaExpression は、Expression から派生した型です。ジェネリック クラス Expressiond504b8e2d633d3ab86a819514662e4f9 は LambdaExpression から派生し、ジェネリック パラメータ TDelegate はデリゲート型である必要があります。
LambdaExpression には、適切な型のデリゲートを作成する Compile メソッドがあります。 Expression
Expression<Func<int, int, int>> expr = (x, y) => x + y; ParameterExpression pex1 = Expression.Parameter(typeof(int), "x");//第一个参数 ParameterExpression pex2 = Expression.Parameter(typeof(int), "y");//第二个参数 BinaryExpression bexp = Expression.Add(pex1, pex2);//主体,加法 //使用Expression.Lambda方法,创建一个委托类型已知的Expression Expression<Func<int,int,int>> lambdaExp = Expression.Lambda<Func<int, int, int>>(bexp, new ParameterExpression[] { pex1, pex2 }); Func<int,int,int> tDelegate = lambdaExp.Compile();//编译成委托 Console.WriteLine(tDelegate(1, 3)); Console.Read();
上記のコードを実行すると、結果は次のようになります: 4.私たちは、基本的に式ツリーを使用して 1+3 の結果を計算する多くのコードを書きました。
以上がC# の式ツリーの簡単な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。