Where式では、Expression<Func<T,bool>>
-を見ています。これは、最も外側のラムダがParameterExpression
タイプがシングルである必要があることを意味しT
ます。
比較が行に関連している場合、(祖先として)これがParameterExpression
あります。ローカル変数の場合、(祖先として)aConstantExpression
がありますが、この定数式の型は、式で使用されるキャプチャされたすべての変数を処理するためにコンパイラによって生成されます。
そのようです:
using System;
using System.Linq.Expressions;
class Foo
{
public string Name { get; set; }
static void Main()
{
var exp = (LambdaExpression) GetExpression();
WalkTree(0, exp.Body, exp.Parameters[0]);
}
static void WriteLine(int offset, string message)
{
Console.WriteLine(new string('>',offset) + message);
}
static void WalkTree(int offset, Expression current,
ParameterExpression param)
{
WriteLine(offset, "Node: " + current.NodeType.ToString());
switch (current.NodeType)
{
case ExpressionType.Constant:
WriteLine(offset, "Constant (non-db)"
+ current.Type.FullName);
break;
case ExpressionType.Parameter:
if (!ReferenceEquals(param, current))
{
throw new InvalidOperationException(
"Unexpected parameter: " + param.Name);
}
WriteLine(offset, "db row: " + param.Name);
break;
case ExpressionType.Equal:
BinaryExpression be = (BinaryExpression)current;
WriteLine(offset, "Left:");
WalkTree(offset + 1, be.Left, param);
WriteLine(offset, "Right:");
WalkTree(offset + 1, be.Right, param);
break;
case ExpressionType.MemberAccess:
MemberExpression me = (MemberExpression)current;
WriteLine(offset, "Member: " + me.Member.Name);
WalkTree(offset + 1, me.Expression, param);
break;
default:
throw new NotSupportedException(
current.NodeType.ToString());
}
}
static Expression<Func<Foo, bool>> GetExpression()
{
Foo foo = new Foo { Name = "abc" };
return row => row.Name == foo.Name;
}
}