بالنظر إلى نوع ExpressionType.MemberAccess, كيف يمكنني الحصول على حقل القيمة ؟

StackOverflow https://stackoverflow.com/questions/238765

  •  04-07-2019
  •  | 
  •  

سؤال

أنا تحليل شجرة التعبير.نظرا NodeType من ExpressionType.MemberAccess, كيف يمكنني الحصول على قيمة هذا الحقل ؟

من C# MSDN مستندات:MemberAccess هو العقدة التي تمثل القراءة من حقل أو الممتلكات.

مدونة مقتطف من شأنه أن يكون بشكل لا يصدق, مفيدة بشكل لا يصدق.شكرا مقدما!!!

قانون بلدي تبدو شيئا مثل هذا:

public static List<T> Filter(Expression<Func<T, bool>> filterExp) 
{
//the expression is indeed a binary expression in this case
BinaryExpression expBody = filterExp.Body as BinaryExpression;

if (expBody.Left.NodeType == ExpressionType.MemberAccess) 
  //do something with ((MemberExpressionexpBody.Left).Name

//right hand side is indeed member access. in fact, the value comes from //aspdroplist.selectedvalue            
if (expBody.Right.NodeType == ExpressionType.MemberAccess)
{
   //how do i get the value of aspdroplist.selected value?? note: it's non-static                        
}

//return a list
}
هل كانت مفيدة؟

المحلول

[تحديث لوضوح]

الأولى ؛ يلقي Expression إلى MemberExpression.

A MemberExpression اثنين من الأشياء من الفائدة:

  • .العضو - PropertyInfo / FieldInfo الأعضاء
  • .التعبير - التعبير لتقييم للحصول على "الكائنات" على .الأعضاء

أيإذا كان يمكنك تقييم .Expression أن "الكائنات" ، .Member هو FieldInfo, ثم يمكنك الحصول على القيمة الفعلية عبر .GetValue(obj) على FieldInfoPropertyInfo هي مشابهة جدا).

المشكلة هي أن تقييم .Expression هو صعب جدا ;-p

ومن الواضح أن كنت محظوظا إذا اتضح أن تكون ConstantExpression - ولكن في معظم الحالات لا ؛ يمكن أن يكون ParameterExpression (في هذه الحالة سوف تحتاج إلى معرفة الفعلية المعلمة القيمة التي تريد تقييم) أو أي تركيبة أخرى من Expressions.

في كثير من الحالات البسيطة (ربما كسول) خيار هو استخدام .Compile() للحصول على .NET framework القيام رفع الأحمال الثقيلة;ثم يمكنك تقييم امدا كما كتبته مندوب (يمر في أي المعلمات أن امدا يتطلب).هذا ليس دائما خيارا ذلك.

لإظهار مدى تعقيد هذا ؛ النظر في هذا المثال تافهة (أين كنت ترميز-الثابت في كل خطوة ، بدلا من اختبار إلخ):

using System;
using System.Linq.Expressions;
using System.Reflection;
class Foo
{
    public string Bar { get; set; }
}

static class Program
{
    static void Main()
    {
        Foo foo = new Foo {Bar = "abc"};
        Expression<Func<string>> func = () => foo.Bar;

        MemberExpression outerMember = (MemberExpression)func.Body;
        PropertyInfo outerProp = (PropertyInfo) outerMember.Member;
        MemberExpression innerMember = (MemberExpression)outerMember.Expression;
        FieldInfo innerField = (FieldInfo)innerMember.Member;
        ConstantExpression ce = (ConstantExpression) innerMember.Expression;
        object innerObj = ce.Value;
        object outerObj = innerField.GetValue(innerObj);
        string value = (string) outerProp.GetValue(outerObj, null);    
    }

}

نصائح أخرى

وأشكركم كثيرا جدا لمارك Gravell أعلاه. أنا حقا عن تقديره مساعدته.

وكما تبين، في حالتي. يمكن حل المشكلة عن طريق:

object value = Expression.Lambda(expBody.Right).Compile().DynamicInvoke();

وشكرا مرة أخرى مارك!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top