假设我有以下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);
我希望Expression.Property(...)工厂中的属性名称(第二个参数)是一个参数,我该怎么做呢?
我希望看到一个看起来像这样的构造函数,但它不存在:
Expresssion.Property(Expression instance, Expression propName)
是否有一些技巧可以将参数化的ConstantExpression转换为所需的字符串或MemberInfo?也许我的方式错了。
我的预感是,因为这些表达式树在编译时变为轻量级IL,所以需要成员访问信息,因此,在构造表达式树时必须提供成员和属性的名称。
感谢您的任何提示!
编辑:想要补充一点,这将用作Enumerable.Where(...)扩展方法的参数,用于确定两个类/实体之间关系的匹配。
答案 0 :(得分:2)
表达式树表示与您在C#/ VB.NET程序中看到的大致的IL结构。您无法参数化该属性表达式,原因与您无法“参数化”以下代码的原因相同:
var x = new MyClass {Id = 1, Name = "hello"};
var propName = "Id";
var xId = x.propName; // <-- This will not compile
如果需要实现此功能,并且表达式树未传递给IQueryable<T>
,则可以编写一个带有对象和字符串的辅助函数,并返回该字符串标识的该对象属性的值;然后,您可以使用Expression.Call
将该辅助函数调用到您正在构建的表达式树中。