C# 创建、组合和缓存lambda表达式
假设我有以下几点C# 创建、组合和缓存lambda表达式,c#,linq,lambda,expression,C#,Linq,Lambda,Expression,假设我有以下几点 foreach (var loop in helper.Loop(x => x.LoopItems)) { loop.Text(x => x.Name); loop.Span(x => x.Name); foreach (var loopItem in loop.Loop(x => x.NestedLoopItems)) { loopItem.Text(x => x.Age); } } 这
foreach (var loop in helper.Loop(x => x.LoopItems))
{
loop.Text(x => x.Name);
loop.Span(x => x.Name);
foreach (var loopItem in loop.Loop(x => x.NestedLoopItems))
{
loopItem.Text(x => x.Age);
}
}
这只适用于我当前的实现,但是它必须编译内部lambda表达式,编译次数与循环项的次数相同。目前,这样做是为了创建表达式来访问列表
索引器。例如,x.ListItems[i]
var methodCallExpression = Expression.Call(_expression, ((PropertyInfo) _expression.Member).PropertyType.GetMethod("get_Item"), Expression.Constant(i));
var expression = Expression.Lambda<Func<TModel, T>>(methodCallExpression, _expression.GetParameter<TModel>());
编译步骤似乎是最昂贵的一步。
如果它需要为每个循环创建一个新的循环,那么是否有任何方法来缓存它,例如
Expression中的i
。常量(i)
需要在每次修改表达式时递增。我不知道CombineeExpression做什么,但是如果可以从Func
更改为Func
(假设索引器始终是int)如果不是,您可以向方法添加另一个泛型,因为您已经在传递“i”以获取表达式中的常量
也不完全确定什么类型的_表达式,所以我不知道这到底是不是在调用重载
var parameterExpression = Expression.Parameter(typeof(int), "i");
var methodCallExpression = Expression.Call(_expression, ((PropertyInfo) _expression.Member).PropertyType.GetMethod("get_Item"), parameterExpression);
var expression = Expression.Lambda<Func<TModel, int, T>>(methodCallExpression, _expression.GetParameter<TModel>(), parameterExpression);
var parameterExpression=Expression.Parameter(typeof(int),“i”);
var methodCallExpression=Expression.Call(_Expression,((PropertyInfo)_Expression.Member).PropertyType.GetMethod(“get_Item”),parameterExpression);
var expression=expression.Lambda(methodCallExpression,_expression.GetParameter(),parameterExpression);
然后,您可以编译表达式并获取Func
,在调用Func时,您将传入“i”值
同样,因为我不知道CombineeExpression是做什么的,但是如果你从中得到一个强类型Func,你可以直接调用它,而不需要调用
另一个旁注:为什么表达式要访问列表索引器?如果您不知道它们的类型,但需要将对象强制转换为IEnumerable(非泛型)并进行迭代,为什么不使用IEnumerable或最差强制转换
var parameterExpression = Expression.Parameter(typeof(int), "i");
var methodCallExpression = Expression.Call(_expression, ((PropertyInfo) _expression.Member).PropertyType.GetMethod("get_Item"), parameterExpression);
var expression = Expression.Lambda<Func<TModel, int, T>>(methodCallExpression, _expression.GetParameter<TModel>(), parameterExpression);