式ツリーとCodeDomの違いは何ですか?どのシナリオでどちらを使用する必要がありますか?
2 に答える
式ツリーには、(たとえば)ASTと多くの共通点があります。コードに直接マップすることはありませんが、アルゴリズムからの構築に非常に適しています。たとえば、数式を解析している場合:
((a + 2) / b)
あれは:
ParameterExpression a = ..., b = ...
var body = Expression.Divide(
Expression.Add(a, Expression.Constant(2)),
b);
var lambda = Expression.Lambda(body,a,b); // optionally with generics
実際、私はこれを正確に行い、オブジェクトツリーを構築するパーサーを使用して、オブジェクトが「ビジター」実装を介して完全な式を生成しました。.NET 4.0では、より豊富な式ツリーのサポートにより、ほとんどのシナリオをサポートし、オンデマンドでコンパイルすることができます。
式のもう1つの重要な用途は、実行時に式を分解できることです。そのため、コードには次のようなものがあります。
Foo(x => x.SomeMethod(1, "abc"));
SomeMethod
メソッド情報1
などを抽出します"abc"
。
codedomはコードにマップされます。それはすべてステートメントなどに関するものであり、通常のコードを書く方法と非常によく似ています。codedomの最も一般的な使用法は、ツールの一部としてのコード生成です。動的コンパイルに使用できますが、正直に言うと難しいです。私はファンではありません。優れた機能は、コードダムツリーが複数の言語で機能する可能性があることです。
ここでの別の候補は、DynamicMethod
および/またはILGenerator
です。これはAST(式)にマップされず、ソースコード(コードダム)を生成するために使用することはできませんが、MSILツールへのフルアクセスを許可します。もちろん、スタックなどの観点から考える必要もありますが、メタプログラミングには非常に効率的で効果的です。
ILGenerator
がハードコアすぎて、codedomがPITAである場合、別のオプションは、文字列としてのコードの実行時生成です。次に、それをパススルーしてCSharpCodeProvider
コンパイルします。これを行うコアランタイムの部分があります(XmlSerializer
IIRC)。
要約すると、次のようになります。
- メタプログラミング:
ILGenerator
またはCSharpCodeProvider
;Expression
4.0でも(ただし、3.5ではかなり制限されています) - ASTの処理:
Expression
- 実行時の解析:
Expression
- 複数の言語でのコード生成:code-dom
式ツリーは、式を作成するために使用されます。実行時にソースコードを作成します。CodeDomは、ソースコードをコンパイルするために使用されます。ビルドする前に存在している必要があります。式ツリーはより柔軟ですが、使用するのがはるかに困難です。
アプリケーションにスクリプトを追加する場合は、CodeDomを使用してください。非常に高度なリフレクションなどを行いたい場合は、エクスプレッションツリーを使用しますが、お勧めしません。