#はじめに
この記事ではC#のExpressionという最高にナウでヤングでイケてるライブラリについて
説明するぜ。
もし、間違ったところがあれば指摘するんだぜ。
#Expressionとは?
まず、Expressionとは、式木を組み立て、コードを動的に生成することができるライブラリだぜ。
この機能を使うことで、関数電卓を作ったり、簡単なコンパイラなんかを作ることができるぜ。
#式木とは?
式木はその名の通り、式の木なんだぜ。
例えば、4+5は
となるのぜ。
もっと複雑な式木を考えてみるぜ。
4+2*3
#Expression実践
じゃあ早速Expressionで4+5の式木を組み立てて見るのぜ。
Expressionはさまざまな種類があるんだが、それらは全てExpressionを継承してるんだぜ。
各種Expressionは、Expressionで定義されているstaticメソッドを使って作成するのぜ。
あっちなみにVisual Studio 2015で動作確認済みだぜ。
using System.Linq.Expressions;
namespace ExpressionQiita
{
class Program
{
static void Main(string[] args)
{
var expr=
Expression.Add(
Expression.Constant(4),
Expression.Constant(5)
);
}
}
}
やったぜ!これで、4+5の式木が組み立てられたぜ!
じゃあ、新しく出てきた2つの関数について説明するぜ。
まずはExpression.Addの定義を紹介するぜ。
BinaryExpression Add(
Expression left,
Expression right
)
ほらわかるだろ?
こいつは、式を二つ受け取り、+演算を行う式を生成するのぜ。
BinaryExpressionは二項演算子を表す式のオブジェクトだぜ。
次にExpression.Constantの定義。
ConstantExpression Constant(
object value
)
こいつは定数を表す式を表現できるのぜ。
例えば、
Expression.Constant(40);
で定数40を表現できるのぜ。
#実際に実行してみよう
じゃあ、式木も作ったし、動的コード生成して、4+5の結果を取得してみよう。
残念、このままじゃ、まだだめなんだぜ。
式木はデリゲートとしてコードを生成するんだ。
つまり、関数だ。
4+5は関数じゃないから生成できないんだぜ。
じゃあ、どうするのか。
まったく簡単!
ラムダ式で包み込むのぜ!
ラムダ式は式だからね!ひゃはー!もちろん式木の仲間さ!
こうなるのぜ ()=>4+5
ラムダ式の構文がわからない?そんなもんしらんわ。
修正したコードはこうだぜ。
using System.Linq.Expressions;
using System;
namespace ExpressionQiita
{
class Program
{
static void Main(string[] args)
{
var expr =
//引数なし、返り値がintのラムダ式を表す
Expression.Lambda<Func<int>>(
Expression.Add(
Expression.Constant(4),
Expression.Constant(5)
)
);
//動的コード生成
Func<int> func=expr.Compile();
//実行してみる
Console.WriteLine(func());
}
}
}
新しく出てきたExpression.Lambdaの定義はこうだぜ。
LambdaExpression Lambda(
Expression body,
params ParameterExpression[] parameters
)
Expression.Lambda(ラムダ式に含めたい式,ラムダ式の引数)
てかんじだぜ
まあラムダ式の引数についてはすぐ後に説明するぜ。
今回は引数はとらないから省略だぜ。
このコードを実行すると()=>4+5というラムダ式を動的コード生成して、
funcに保存しているぜ。
あとはfuncはふつーにデリゲートとして使えるんだぜ。
そのあと、Console.WriteLine(func())でfuncの計算結果 9を表示しているぜ。
#引数を渡そう!
毎回毎回4+5の結果を表示するだけの関数なんていらねー!
というわけで、(int x,int y)=>x+yな関数を生成するぜ。
using System.Linq.Expressions;
using System;
namespace ExpressionQiita
{
class Program
{
static void Main(string[] args)
{
var x = Expression.Parameter(typeof(int),"x");
var y = Expression.Parameter(typeof(int));
var expr =
//引数なし、返り値がintのラムダ式を表す
Expression.Lambda<Func<int,int,int>>(
Expression.Add(
x,
y
),x,y
);
//動的コード生成
Func<int,int,int> func=expr.Compile();
//実行してみる
Console.WriteLine(func(4,6));
}
}
}
Expression.Lambda関数の第二、第三には、引数を設定してるのぜ。
こうすることで、Int型の引数を2つ受け取り、x,yに代入できるぜ。
今回の例だと、4と6を引数x,yとして受け取り、計算しているぜ。
【需要があったら続きかきます】