現在の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
Anonymous
September 03, 2008
PingBack from http://hoursfunnywallpaper.cn/?p=4558Anonymous
September 03, 2008
PingBack from http://informationsfunnywallpaper.cn/?p=3736Anonymous
September 03, 2008
PingBack from http://www.easycoded.com/%e7%8f%be%e5%9c%a8%e3%81%aedlr%e3%81%abtreecompiler%e3%81%af%e5%ad%98%e5%9c%a8%e3%81%99%e3%82%8b%e3%81%ae%e3%81%8b/Anonymous
October 05, 2008
VS2008とDLRベータ4の環境で動かそうとしたのですが、 MyFunc myFunc = lambdExpression.Compile<MyFunc>(); がエラーになってしまいました。 以下のように変更すると、とりあえず実行できます。 var del2 = lambdaExpression.Compile(); del2.DynamicInvoke();