現在のDLRにTreeCompilerは存在するのか


以前のDLRのASTのみを使うというエントリでTreeCompilerを使う方法を説明しました。最近のDLRでは、どうなったでしょうか。結論から云えば、IronPython 2.0 ベータ4ではTreeCompilerは無くなっています。その代わりに、以下のような方法を使うことでDLRのASTのみを使うことができます。

using System;
using System.Collections.Generic;
using System.Text;

using System.Linq.Expressions;
using Microsoft.Scripting.Ast;

namespace AstTest
{
class Program
{
delegate void MyFunc();

static void Main(string[] args)
{
LambdaBuilder lambdaBuilder = Utils.Lambda(
typeof(void), “MyFunc”, Annotations.Empty);

var helper = typeof(Console).GetMethod(“WriteLine”,
new[] {typeof(string)});

// 1行の場合
//lambdaBuilder.Body = Expression.Call(
// helper, Expression.Constant(“Hello, world”));
// 複数行の場合
lambdaBuilder.Body = Expression.Block(
Expression.Call(helper,
Expression.Constant(“Hello, world”)),
Expression.Call(helper,
Expression.Constant(“Hello, world”)),
Expression.Call(helper,
Expression.Constant(“Hello, world”)));

LambdaExpression lambdExpression = lambdaBuilder.MakeLambda();
// 型パラメータを作成したコードブロックに一致させる
MyFunc myFunc = lambdExpression.Compile<MyFunc>();
myFunc();

Console.ReadKey();
}
}
}



これにMicrosoft.Scripting.dllとMicrosoft.Scripting.Core.dllへ参照を追加し実行すれば、「Hello, world」の文字列が3回コンソールに出力されます。


この内容からDLRのASTの基本的な使い方を理解することができます。それは、以下のようなことです。



  • LambdaBuilder:戻り値型やメソッド名などを指定する。

  • LambdaBuilder.Body:Expressionクラス(ASTによって作成される式)のインスタンス。

  • MakeLambdaメソッド:MakeLambdaメソッドによって、LambdaExpressionを作成する。

  • LambdaExpression.Compileメソッド:LambdaExpressionをコンパイルして、結果をデリゲートのインスタンスとして返す。

  • デリゲートを呼び出す。

この使い方を理解できれば、If文やループなどに応用することができます。


追記:Naitoさんよりフィードバックを頂きました。正確にはBeta4でCompile<T>()メソッドが削除されていて、Beta5に含まれています。このためNaitoさんのご指摘通り、Compile()メソッドを使って、Microsoft.Actionクラスを受け取り、DynamicInvokeメソッドで実行することができます。

Comments (4)

  1. Naito より:

    VS2008とDLRベータ4の環境で動かそうとしたのですが、

    MyFunc myFunc = lambdExpression.Compile<MyFunc>(); がエラーになってしまいました。

    以下のように変更すると、とりあえず実行できます。

    var del2 = lambdaExpression.Compile();

    del2.DynamicInvoke();

Skip to main content