Могу ли я параметризировать имя свойства выражения PropertyExpression с помощью выражений LINQ? - PullRequest
4 голосов
/ 11 января 2012

Предположим, у меня есть следующее LambdaExpression:

var itemParam = Expression.Parameter(typeof(Thing), "thing");
var someValue = "ABCXYZ123"; // value to compare

LambdaExpression lex = Expression.Lambda(
  Expression.Equal(
    Expression.Property(itemParam, "Id"), // I want ID to be a Body expression parameter
    Expression.Constant(someValue)
  ), itemParm);

И я хочу, чтобы имя свойства (2-й параметр) в фабрике Expression.Property (...) было параметром. Как мне это сделать?

Я надеялся увидеть конструктор, который выглядит так, но его не существует:

Expresssion.Property(Expression instance, Expression propName)

Есть ли у меня какой-то трюк, который может преобразовать параметризованное выражение ConstantExpression в нужную строку или MemberInfo? Может быть, я поступаю об этом неправильно.

Моя догадка заключается в том, что, поскольку эти деревья выражений при компиляции становятся легковесными IL, эта информация о доступе к элементам требуется, поэтому имена конструкторов и свойства должны указываться при построении деревьев выражений.

Спасибо за любые советы!

РЕДАКТИРОВАТЬ: Хотел добавить, что это будет использоваться в качестве аргумента для метода расширения Enumerable.Where (...) для определения соответствия на отношения между двумя классами / объектами.

1 Ответ

2 голосов
/ 11 января 2012

Деревья выражений представляют собой структуры IL, которые примерно того же типа, что вы видите в своих программах на C # / VB.NET.Вы не можете параметризовать это выражение свойства по той же причине, по которой вы не можете «параметризовать» следующий код:

var x = new MyClass {Id = 1, Name = "hello"};
var propName = "Id";
var xId = x.propName; // <-- This will not compile

Если вам нужно реализовать эту функцию, и ваши деревья выражений не передаются в IQueryable<T>, выможет написать вспомогательную функцию, принимающую объект и строку, и возвращающую значение свойства этого объекта, идентифицированного строкой;затем вы можете использовать Expression.Call для вызова этой вспомогательной функции в строящемся дереве выражений.

...