بالنظر إلى نوع ExpressionType.MemberAccess, كيف يمكنني الحصول على حقل القيمة ؟
-
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)
على FieldInfo
(و PropertyInfo
هي مشابهة جدا).
المشكلة هي أن تقييم .Expression
هو صعب جدا ;-p
ومن الواضح أن كنت محظوظا إذا اتضح أن تكون ConstantExpression
- ولكن في معظم الحالات لا ؛ يمكن أن يكون ParameterExpression
(في هذه الحالة سوف تحتاج إلى معرفة الفعلية المعلمة القيمة التي تريد تقييم) أو أي تركيبة أخرى من Expression
s.
في كثير من الحالات البسيطة (ربما كسول) خيار هو استخدام .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();
وشكرا مرة أخرى مارك!