Учитывая тип ExpressionType.MemberAccess, как мне получить значение поля?

Я разбираю дерево выражений. Учитывая 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
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
33
0
8 952
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

[обновлено для ясности]

Первый; преобразовать Expression в MemberExpression.

У MemberExpression есть два интересных момента:

  • .Член - PropertyInfo / FieldInfo члену
  • .Expression - выражение, которое нужно оценить, чтобы получить "объект" для .Member.

т.е. если вы можете оценить .Expression как "obj", а .Member - это FieldInfo, то вы можете получить фактическое значение через .GetValue(obj) на FieldInfoPropertyInfo очень похож).

Проблема в том, что оценить .Expression очень сложно ;-p

Очевидно, вам повезет, если окажется, что это ConstantExpression, но в большинстве случаев это не так; это может быть ParameterExpression (в этом случае вам нужно знать фактическое значение параметра, которое вы хотите оценить) или любая другая комбинация Expression.

Во многих случаях простой (возможно, ленивый) вариант - использовать .Compile(), чтобы заставить платформу .NET выполнять тяжелую работу; затем вы можете оценить лямбда как типизированный делегат (передав любые параметры, которые требуются лямбда). Однако это не всегда вариант.

Чтобы показать, насколько это сложно; рассмотрим этот тривиальный пример (где я жестко программировал на каждом этапе, а не тестировал и т. д.):

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);    
    }

}

Большое спасибо, Марк. Значение свойства .Expression ... кое-что более интересное: {value (ASP.usercontrols_mycontro_ascx) .controlname}

Keith Fitzgerald 27.10.2008 02:48

Я много делаю с дженериками и отражением, поэтому получение значения через propertyinfo / fieldinfo не работает, потому что я не уверен, откуда вытащить ссылающийся объект ... могу ли я вытащить это из выражения members или methodinfo?

Keith Fitzgerald 27.10.2008 02:49

Это будет работать ... но проблема в том, что вам нужно оценить .Expression как значение для подачи в качестве "obj" для FieldInfo / PropertyInfo. Разве вы не можете просто использовать .Compile () и выполнять лямбда-выражение в качестве делегата? Намного проще, чем разбирать ...

Marc Gravell 27.10.2008 03:07

Обратите внимание: если лямбда параметризована, но у вас нет конкретного параметра - тогда вы будете бороться ... но такие вещи, как ConstantExpression, должны работать нормально.

Marc Gravell 27.10.2008 03:08

Большое спасибо, Марк !!! действительно ... выше и выше здесь. в конечном итоге проблема в том, что левая часть является двоичным выражением ... а правая часть не является постоянным выражением. я собираюсь обновить свой вопрос с помощью некоторого кода

Keith Fitzgerald 27.10.2008 04:22

Большое спасибо Марку Гравеллу выше. Я очень признателен за его помощь.

Оказывается, в моем случае. проблему можно решить с помощью:

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

Еще раз спасибо, Марк!

или лучше object value = Expression.Lambda<Func<object>>(Expression.Convert(expBody.R‌​ight, typeof(object))).Compile().Invoke()

Double Down 13.03.2011 17:19

Печальная часть: это очень медленно.

ren 03.06.2016 16:43

Другие вопросы по теме