Linq表达式快照索引值

本文关键字:索引值 快照 表达式 Linq | 更新日期: 2023-09-27 18:18:59

这个问题最容易用代码描述:

class Program
{
    static void Main(string[] args)
    {
        int index = 0;
        var listOfExpressions = new List<ClassHoldingExpression>();
        listOfExpressions.Add(new ClassHoldingExpression((a) => a.Dict[index]));
        index++;
        listOfExpressions.Add(new ClassHoldingExpression((a) => a.Dict[index]));
        var dictClass = new ClassWithDict();
        dictClass.Dict[0] = "Test 1";
        dictClass.Dict[1] = "Test 2";
        foreach (var expr in listOfExpressions)
            Console.WriteLine((string)expr.Eval(dictClass));
    }
}

public class ClassWithDict
{
    public ClassWithDict()
    {
        Dict = new Dictionary<int, object>();
    }
    public Dictionary<int, object> Dict { get; set; }
}
public class ClassHoldingExpression
{
    private Expression<Func<ClassWithDict, object>> Expression { get; set; }
    public ClassHoldingExpression(Expression<Func<ClassWithDict, object>> expr)
    {
        Expression = expr;
    }
    public object Eval(ClassWithDict source)
    {
        return this.Expression.Compile().Invoke(source);
    }
}
//Output: 
//Test 2
//Test 2
//Desired:
//Test 1
//Test 2

基本上,我想用多个值填充该字典,并在特定索引处用不同的表达式填充ClassHoldingExpression列表。然而,它似乎回头看并寻找"index"的当前值,而不是将当前值保存到表达式中。我怎样才能强制它保存index的当前到表达式?

Linq表达式快照索引值

你必须创建一个新的变量来保存你想要的值。

int index0 = 0;
var listOfExpressions = new List<ClassHoldingExpression>();
listOfExpressions.Add(new ClassHoldingExpression((a) => a.Dict[index0]));
int index1 = index0 + 1;
listOfExpressions.Add(new ClassHoldingExpression((a) => a.Dict[index1]));

如果您需要在循环中这样做,请在捕获它之前为每个循环迭代定义一个变量。

看起来像是闭包问题。

foreach (var TMPexpr in listOfExpressions){
   var expr = TMPexpr ;  // take LOCAL copy
   Console.WriteLine((string)expr.Eval(dictClass));
}

类似SO post