かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Expression Tree

DLINQもどきみたいなものを作ろうと思ったけど、そのためにはExpression周辺のことについてまず勉強せねばなるまい。
ということで軽く入門をしてみた。

ラムダ式というのがC#3.0から追加される。
ラムダ式は、Expressionに代入することが出来るようだ。

Expression<Func<int, bool>> e = (i) => i == 10;

この、Expressionには、ラムダ式を解析した結果がもれなく入ってるとか!
ということで、Expressionあたりのメンバの値を適当に出力してみた。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace Linq
{
    class Program
    {
        static void Main(string[] args)
        {
            Expression<Func<int, bool>> e = (i) => i == 10;
            PrintExpression("!Expression!", e);
        }

        private static void PrintExpression(string head, Expression e)
        {
            Console.WriteLine("----" + head + "----");
            Console.WriteLine("Type: " + e.Type);
            Console.WriteLine("NodeType: " + e.NodeType);
            if (e is LambdaExpression)
            {
                LambdaExpression le = (LambdaExpression)e;
                foreach (var p in le.Parameters)
                {
                    PrintExpression("Param", p);
                }
                PrintExpression("Body", le.Body);
            }
            else if (e is BinaryExpression)
            {
                BinaryExpression be = (BinaryExpression) e;
                PrintExpression("Left", be.Left);
                PrintExpression("Right", be.Right);
            }
            else if (e is ParameterExpression)
            {
                ParameterExpression pe = (ParameterExpression)e;
                Console.WriteLine("Name: " + pe.Name);
            }
            else if (e is ConstantExpression)
            {
                ConstantExpression ce = (ConstantExpression)e;
                Console.WriteLine("Value: " + ce.Value);
            }
        }
    }
}

どうやら、最初のExpression>はLambdaExpressionというものらしい。
BodyとParametersあたりで、どんなんか概要がつかめる。
後は、適当にそのときそのときの型をダンプしてみて、どんな型があるのか調べてみた。
出力は↓のようになった。

----!Expression!----
Type: System.Linq.Func`2[System.Int32,System.Boolean]
NodeType: Lambda
----Param----
Type: System.Int32
NodeType: Parameter
Name: i
----Body----
Type: System.Boolean
NodeType: Equal
----Left----
Type: System.Int32
NodeType: Parameter
Name: i
----Right----
Type: System.Int32
NodeType: Constant
Value: 10

これだけの情報があれば、もとの(int i) => i == 10にたどり着けそうだ。


とりあえずここで時間切れorz