Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建、组合和缓存lambda表达式_C#_Linq_Lambda_Expression - Fatal编程技术网

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