如何在 C# 中使用 LinqExpression 创建一个动态获取 属性 的表达式?
How to create an expression getting a property dynamically using LinqExpression in c#?
我正在尝试创建一个 linq 表达式,根据 SearchFilter 对象参数从 Student 对象动态获取 属性。
问题是 Expression.Property(expr, string) 要求 属性 名称的字符串。而且我无法从 ParameterExpression 中检索字符串。我尝试了这个,但我被卡住了......作为(字符串)当然的演员阵容不起作用。关于如何继续的任何线索?
检查下面的代码:
using System;
using System.Linq.Expressions;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
var student = new Student
{
FirstName = "John",
Address = new Address
{
City = "New York",
ZipCode = 10005
}
};
var filter = new SearchFilter
{
Rule = "ZipCode"
};
var studentParamExpr = Expression.Parameter(typeof(Student), "s");
var filterParamExpr = Expression.Parameter(typeof(SearchFilter), "filter");
var lambdaExpr = Expression.Lambda(
CreateStudentAddressRuleAccessor(studentParamExpr, filterParamExpr),
new ParameterExpression[] { studentParamExpr, filterParamExpr });
var expression = lambdaExpr.Compile().DynamicInvoke(student, filter);
}
public static Expression CreateStudentAddressRuleAccessor(ParameterExpression student, ParameterExpression filter)
{
var ruleExpr = Expression.Property(filter, "Rule");
string rule = (string)ruleExpr;
var resultExpr = Expression.Property(Expression.Property(student, "Address"), rule);
return resultExpr;
}
}
public class Student
{
public string FirstName { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string City { get; set; }
public int ZipCode { get; set; }
}
public class SearchFilter
{
public string Rule { get; set; }
}
}
Lambda 主体不要求所有参数都是表达式。
从 lambda 参数列表中删除过滤器并将过滤器 arg 的类型更改为 SearchFilter,如下所示:
static void Main(string[] args)
{
...
var studentParamExpr = Expression.Parameter(typeof(Student), "s");
var lambdaExpr = Expression.Lambda(
CreateStudentAddressRuleAccessor(studentParamExpr, filter),
new ParameterExpression[] { studentParamExpr });
var expression = lambdaExpr.Compile().DynamicInvoke(student);
Console.WriteLine($"Lambda expression = {lambdaExpr}");
Console.WriteLine($"Expression = {expression}");
}
public static Expression CreateStudentAddressRuleAccessor(ParameterExpression student, SearchFilter filter)
{
var resultExpr = Expression.Property(Expression.Property(student, "Address"), filter.Rule);
return resultExpr;
}
我正在尝试创建一个 linq 表达式,根据 SearchFilter 对象参数从 Student 对象动态获取 属性。
问题是 Expression.Property(expr, string) 要求 属性 名称的字符串。而且我无法从 ParameterExpression 中检索字符串。我尝试了这个,但我被卡住了......作为(字符串)当然的演员阵容不起作用。关于如何继续的任何线索?
检查下面的代码:
using System;
using System.Linq.Expressions;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
var student = new Student
{
FirstName = "John",
Address = new Address
{
City = "New York",
ZipCode = 10005
}
};
var filter = new SearchFilter
{
Rule = "ZipCode"
};
var studentParamExpr = Expression.Parameter(typeof(Student), "s");
var filterParamExpr = Expression.Parameter(typeof(SearchFilter), "filter");
var lambdaExpr = Expression.Lambda(
CreateStudentAddressRuleAccessor(studentParamExpr, filterParamExpr),
new ParameterExpression[] { studentParamExpr, filterParamExpr });
var expression = lambdaExpr.Compile().DynamicInvoke(student, filter);
}
public static Expression CreateStudentAddressRuleAccessor(ParameterExpression student, ParameterExpression filter)
{
var ruleExpr = Expression.Property(filter, "Rule");
string rule = (string)ruleExpr;
var resultExpr = Expression.Property(Expression.Property(student, "Address"), rule);
return resultExpr;
}
}
public class Student
{
public string FirstName { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string City { get; set; }
public int ZipCode { get; set; }
}
public class SearchFilter
{
public string Rule { get; set; }
}
}
Lambda 主体不要求所有参数都是表达式。 从 lambda 参数列表中删除过滤器并将过滤器 arg 的类型更改为 SearchFilter,如下所示:
static void Main(string[] args)
{
...
var studentParamExpr = Expression.Parameter(typeof(Student), "s");
var lambdaExpr = Expression.Lambda(
CreateStudentAddressRuleAccessor(studentParamExpr, filter),
new ParameterExpression[] { studentParamExpr });
var expression = lambdaExpr.Compile().DynamicInvoke(student);
Console.WriteLine($"Lambda expression = {lambdaExpr}");
Console.WriteLine($"Expression = {expression}");
}
public static Expression CreateStudentAddressRuleAccessor(ParameterExpression student, SearchFilter filter)
{
var resultExpr = Expression.Property(Expression.Property(student, "Address"), filter.Rule);
return resultExpr;
}