かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

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