トップ回答者
ConstantExpressionから変数の値を取得したい

質問
回答
-
var point = new Point( 1, 2 );
Expression<Func<int>> lambda = () => point.Y;
// lambda式は
var bodyExpression = lambda.Body as MemberExpression;
// 「point」式と
var pointExpression = bodyExpression.Expression as MemberExpression;
// Point.Yプロパティアクセス
var propertyY = bodyExpression.Member as PropertyInfo;
// 「point」式はlambda式の入力となっている定数のうち
var constantExpression = pointExpression.Expression as ConstantExpression;
// 「point」という名前を持っている
var fieldPoint = pointExpression.Member as FieldInfo;
var valuePoint = (Point)fieldPoint.GetValue( constantExpression.Value );
var valueY = (int)propertyY.GetValue( valuePoint, null );
Console.WriteLine( valueY );
うーん、わかってはいたけど、大変ですね(^^;- 回答としてマーク 和和和 2009年6月8日 0:36
-
これは長い間悩んでいたものを解決してくださりありがとうございました。
これを参考にして深いオブジェクトの参照も取得できるようにしてみました。
private static Object オブジェクト取得(MemberExpression MemberExpression,PropertyInfo PropertyInfo) { return PropertyInfo.GetValue(オブジェクト取得(MemberExpression),null); } private static Object オブジェクト取得(MemberExpression MemberExpression) { var MemberExpression_Expression=MemberExpression.Expression; if(MemberExpression_Expression.NodeType==ExpressionType.MemberAccess) { return オブジェクト取得(MemberExpression_Expression as MemberExpression,MemberExpression.Member as PropertyInfo); } else { var Constant=MemberExpression_Expression as ConstantExpression; var FieldInfo=MemberExpression.Member as FieldInfo; return FieldInfo.GetValue(Constant.Value); } } public class Point2{ private Point1 _Point1=new Point1(); public Point1 Point1 { get { return this._Point1; } } } public class Point1 { private Point _Point0=new Point(3,4); public Point Point0 { get { return this._Point0; } } } private void Form1_Load(object sender,EventArgs e) { var 変数=5; var point0=new Point(1,2); var point1=new Point1(); var point2=new Point2(); Expression<Func<int>> lambda=() => 変数; Expression<Func<int>> lambda0=() => point0.X; Expression<Func<int>> lambda1=() => point1.Point0.X; Expression<Func<int>> lambda2=() => point2.Point1.Point0.X; var 変数値=オブジェクト取得(lambda.Body as MemberExpression); var point0値=オブジェクト取得(lambda0.Body as MemberExpression); var point1値=オブジェクト取得(lambda1.Body as MemberExpression); var point2値=オブジェクト取得(lambda2.Body as MemberExpression); }
自分でLINQ to SQL作ってみたいんで通常の四則演算や関数やLINQ to Objectを実行時に定数化してクエリ式に渡したいのがそもそもの目的でした。- 回答としてマーク 和和和 2009年6月8日 0:36
すべての返信
-
var point = new Point( 1, 2 );
Expression<Func<int>> lambda = () => point.Y;
// lambda式は
var bodyExpression = lambda.Body as MemberExpression;
// 「point」式と
var pointExpression = bodyExpression.Expression as MemberExpression;
// Point.Yプロパティアクセス
var propertyY = bodyExpression.Member as PropertyInfo;
// 「point」式はlambda式の入力となっている定数のうち
var constantExpression = pointExpression.Expression as ConstantExpression;
// 「point」という名前を持っている
var fieldPoint = pointExpression.Member as FieldInfo;
var valuePoint = (Point)fieldPoint.GetValue( constantExpression.Value );
var valueY = (int)propertyY.GetValue( valuePoint, null );
Console.WriteLine( valueY );
うーん、わかってはいたけど、大変ですね(^^;- 回答としてマーク 和和和 2009年6月8日 0:36
-
これは長い間悩んでいたものを解決してくださりありがとうございました。
これを参考にして深いオブジェクトの参照も取得できるようにしてみました。
private static Object オブジェクト取得(MemberExpression MemberExpression,PropertyInfo PropertyInfo) { return PropertyInfo.GetValue(オブジェクト取得(MemberExpression),null); } private static Object オブジェクト取得(MemberExpression MemberExpression) { var MemberExpression_Expression=MemberExpression.Expression; if(MemberExpression_Expression.NodeType==ExpressionType.MemberAccess) { return オブジェクト取得(MemberExpression_Expression as MemberExpression,MemberExpression.Member as PropertyInfo); } else { var Constant=MemberExpression_Expression as ConstantExpression; var FieldInfo=MemberExpression.Member as FieldInfo; return FieldInfo.GetValue(Constant.Value); } } public class Point2{ private Point1 _Point1=new Point1(); public Point1 Point1 { get { return this._Point1; } } } public class Point1 { private Point _Point0=new Point(3,4); public Point Point0 { get { return this._Point0; } } } private void Form1_Load(object sender,EventArgs e) { var 変数=5; var point0=new Point(1,2); var point1=new Point1(); var point2=new Point2(); Expression<Func<int>> lambda=() => 変数; Expression<Func<int>> lambda0=() => point0.X; Expression<Func<int>> lambda1=() => point1.Point0.X; Expression<Func<int>> lambda2=() => point2.Point1.Point0.X; var 変数値=オブジェクト取得(lambda.Body as MemberExpression); var point0値=オブジェクト取得(lambda0.Body as MemberExpression); var point1値=オブジェクト取得(lambda1.Body as MemberExpression); var point2値=オブジェクト取得(lambda2.Body as MemberExpression); }
自分でLINQ to SQL作ってみたいんで通常の四則演算や関数やLINQ to Objectを実行時に定数化してクエリ式に渡したいのがそもそもの目的でした。- 回答としてマーク 和和和 2009年6月8日 0:36