[C#][ラムダ式][式木] Expression として扱えるラムダ式と扱えないラムダ式
前回、「匿名メソッドとラムダ式の違い」と云う記事で、匿名メソッドとラムダ式の意味の違いについて考えた。
それについて、少し補足しておきたい。
「ラムダ式を Expression として扱っている場合は、匿名メソッドは代わりにはならない」と述べたが、ラムダ式であれば何でも Expression として扱える訳ではないのだ。
■ Expression として扱えるラムダ式
ラムダ式として足し算を行うだけの (x, y) => x + y と云うシンプルなものを用意し、これを Expression で受けてみる。
using System; using System.Linq.Expressions; class Program { static void Main() { Expression<Func<int, int, int>> expression = (x, y) => x + y; } }
これは特に問題ない。
■ Expression として扱えないラムダ式
ラムダ式の => より右の部分には式だけでなくステートメントのブロックも置くことができる。
このラムダ式の => より右の部分を、式ではなく、ステートメントのブロックに変えてみよう。
例えば、(x, y) => { return x + y; } とし、これを Expression で受けてみる。どうなるだろうか?
using System; using System.Linq.Expressions; class Program { static void Main() { Expression<Func<int, int, int>> expression = (x, y) => { return x + y; }; } }
すると今度は、「ステートメント本体を含むラムダ式は、式のツリーに変換できません」というコンパイル エラーになる。
つまり、ラムダ式の => の右の部分が式である場合は Expression として扱えるが、ステートメントのブロックである場合は Expression として扱えないのだ。
■ 考察
「式でないものは式として扱えない」と云う、云わば当たり前の結果だ。
ところで、F# や Scala、Haskell などの関数型プログラミングをより得意とする言語では、if 等多くのものが式として扱える。
それらと比較すると、C# ではまだまだ式として書ける範囲は少ない。
例えば、if は文だ (勿論 C# でも三項演算子で書けるものは式で表現できる)。
だが、C# でもっと多くのものが、F# や Scala、Haskell などの言語のように文でなく式で表せるようになれば、益益 Expression で扱える範囲が増える、と云うことになるだろう。
■ 今回のまとめ
今回は、前回の記事の補足を軽く行った。
今後、ラムダ式を Expression として利用する例を何回かに分けて、紹介していく予定だ。
次回は、先ず Expression そのものへの理解を深めるために Expression の構造を調べてみたいと思う。
ディスカッション
コメント一覧
まだ、コメントがありません