C# 在for循环中使用LINQ Where时,如何修复索引越界错误?

C# 在for循环中使用LINQ Where时,如何修复索引越界错误?,c#,linq,C#,Linq,我有一个字典数据结构列表。我想对其进行过滤,以仅获取那些与输入到过滤方法的某些键值对匹配的字典条目。这些键值对的数量因调用而异 我编写了以下代码来实现我想要做的事情。如果我使用GetPlanningDataMatching方法,它可以完美地工作,没有任何问题 但是,如果我使用GetPlanningDataMatching_alt方法,我会在第[planningDataKeys[inx]]==planningDataValues[inx]行得到索引越界错误。inx等于planningDataKey

我有一个字典数据结构列表。我想对其进行过滤,以仅获取那些与输入到过滤方法的某些键值对匹配的字典条目。这些键值对的数量因调用而异

我编写了以下代码来实现我想要做的事情。如果我使用GetPlanningDataMatching方法,它可以完美地工作,没有任何问题

但是,如果我使用GetPlanningDataMatching_alt方法,我会在第[planningDataKeys[inx]]==planningDataValues[inx]行得到索引越界错误。inx等于planningDataKeys.Count

我做错了什么

我的问题与不同,否则我的两个方法-GetPlanningDataMatching和GetPlanningDataMatching_alt都会失败

// Build this data structure in the class constructor (not shown here)
List<Dictionary<String, String>> planningData = null;

// planningDataKeys.Count is always same as planningDataValues.Count
public List<Dictionary<String, String>> GetPlanningDataMatching_alt(List<String> planningDataKeys, List<String> planningDataValues)
{
    IEnumerable<Dictionary<String, String>> matchingPlanningData = null;
    for (int inx = 0; inx < planningDataKeys.Count; ++inx)
        matchingPlanningData = (inx == 0 ? planningData : matchingPlanningData)
                                        .Where(row => row[planningDataKeys[inx]] == planningDataValues[inx]);
    return matchingPlanningData.ToList();
}

// planningDataKeys.Count is always same as planningDataValues.Count
public List<Dictionary<String, String>> GetPlanningDataMatching(List<String> planningDataKeys, List<String> planningDataValues)
{
    List<Dictionary<String, String>> matchingPlanningData = null;
    for (int inx = 0; inx < planningDataKeys.Count; ++inx)
        matchingPlanningData = (inx == 0 ? planningData : matchingPlanningData)
                                        .Where(row => row[planningDataKeys[inx]] == planningDataValues[inx])
                                        .ToList();
    return matchingPlanningData;
}

我的直觉是你的问题在于没有在for循环中实现集合

例如,在第二种方法中,您在每次迭代中都执行.ToList,这就是正确捕获inx的原因

但是在_alt方法中,您捕获了对inx的引用,每次迭代都会增加inx,然后使用向后的++inx,而不是典型的inx++,这意味着在最后一次迭代中它将等于计数

最后,调用IEnumerable上的.tolist,这会导致代码查看数组中索引之外的索引

太感人了,托利斯会把它修好的

作为旁注,从可读性的角度来看,这整件事似乎真的很奇怪

来一杯怎么样

public List<Dictionary<String, String>> GetPlanningDataMatching(Func<KeyValuePair, Bool> predicate)
{
    return this.planningData.Where(predicate).ToList();
}
然后打电话,做一些类似的事情

var stuff = new Dictionary<String, String>(){{"a", "b"}};
WhateverClass()
.GetPlanningDataMatching(kp => stuff.ContainsKey(kp.Key) && stuff[kp.Key] == kp.Value);

planningDataKeys.Count是否等于字典中的项数?我想知道将索引缩写为inx的目的是什么;另请参见。@ŇɏssaPøngjǣrdenlarp:我的问题与该问题不同,否则我的两个方法-GetPlanningDataMatching和GetPlanningDataMatching_alt都会失败,并出现索引越界错误。如果使用增量,则增量后运算符inx++必须在增量之前存储该值。在我的情况下,我没有使用增量之前的inx值。因此,inx++和++inx具有相同的效果,只是++inx的效率稍高一些。当你说moving.ToList会修复它-你是说_alt方法不起作用。你可能会发现一些。。。我在读林克的故事。似乎LINQ方法是使用延迟执行来实现的,并且LINQ查询在枚举结果之前不会执行。这可能是GetPlanningDataMatching之所以有效的原因,因为由于ToList调用,每个循环中都会枚举结果。但是GetPlanningDataMatching_alt方法在所有循环迭代结束并且该从该方法返回之前不会枚举结果?@YogiWatcher是的,这正是我在回答中所说的