C#3.0のラムダ式は、そのまま実行する場合と、コードをデータとして表現したものに変換する場合があるらしい。
Expression<Func<int,Bool>> e = (int x) => x % 2 == 0; といった感じでExpressionに入れると、コードのデータに変換されるようだ。
単項演算はUnaryExpression,二項演算はBinaryExpressionでうんにゃらかんにゃらで、コードを全部Expressionオブジェクトのツリーにする。これはすごく使い道がありそうだ。
実際DLinqはこのツリーを読んで、SQL文に変換するらしい。普通に実行するためには、
Func<int,bool> func = e.Compile();
if(func(0))...
コンパイルして実行すればいいようだ。普通に、
Func<int,bool> func = x => x % 2 == 0;
まっすぐ書けば、ツリーにはされずコンパイルする必要もない。
うーんと、とりあえず、プログラムを全部ラムダ式で書いてExpressionに格納するようにすればILを見なくてもエラーチェックが出来るな。ダメだ。死んだ方がマシな発想だ。言語の全能力を持ったツリーをチェックするなんてのは自己矛盾ですよ。そんなこと出来るならコンパイラがやってますよ。
ラムダ式を取るメソッドを作って、このメソッドに入れるラムダ式ではこれしかやっちゃいけません、という規約を作れば、そのメソッドの呼び出しを全部探して…ダメだ。IL読まなきゃならなくなった。
ActCode(SGのコード)の場合は、シングルトンであることが保障されたあるクラスの継承クラスでしかActCodeを作らないというルールを作って、そのSingletonを全部探してリフレクションでActCodeを全部探してその中のActCodeを一個一個みている。
同じように、Expressionをコンストラクタの引数に取るクラスを作って、そのインスタンスを全部から探してエラーチェックすることは出来る。
しかし相変わらず「全呼び出しを探す」とかやるならIL読まなきゃならんな。それならソースコード読んだ方がいいぐらいの勢いだがソースコード読んだところで中身がどうなるのかがわかんないから厳しい。IL読んだところでやっぱり分からない。今のアプローチでだいぶ満足してるからこれ以上はいいかな。しかし何かありそうな予感はあるのだけど。