指数超出范围。必须是非负误差

时间:2013-10-24 13:45:02

标签: c# asp.net-mvc

我不断获得超出范围异常的索引。不得为非负数且小于集合的大小。

问题是当我检查toRemove时,计数低于受访者。那么这个错误是怎么发生的?如果5位于respondentstoRemove仅为3,则该错误是如何发生的?

var respondents = RespondentRepository.GetRespondents(UserSession, fieldsToInclude);

// iterate through the respondents. If search query not like results throw the result away.
List<int> toRemove = new List<int>();
for (int i = 0; i < respondents.Count; i++)
{
    if (!respondents[i].EmailAddresses.Any())
        toRemove.Add(i);
    else
    {
        bool checkSingleEmail = false;
        bool checkAllEmails = false;
        for (int j = 0; j < respondents[i].EmailAddresses.Count; j++)
        {
            checkSingleEmail = respondents[i].EmailAddresses[j].Address.ToString().Contains(query);

            if (checkSingleEmail == true)
                checkAllEmails = true;

            if (respondents[i].EmailAddresses.Count == 1 && j == 0 && checkAllEmails == false)
                toRemove.Add(i);
            else if (checkAllEmails == false && j+1 == respondents[i].EmailAddresses.Count)
                toRemove.Add(i);
        }
    }
}

foreach (var respRemove in toRemove)
{
    respondents.RemoveAt(respRemove);
}

4 个答案:

答案 0 :(得分:6)

如果您想使用索引,可以这样写:

foreach (var respRemove in toRemove.OrderByDesc(r => r).ToList())
{
    respondents.RemoveAt(respRemove);
}

答案 1 :(得分:4)

发生异常是因为您从列表中删除了项目,然后假设其他项目仍然在同一索引处。请尝试保留对该项目的引用:

var respondents = RespondentRepository.GetRespondents(UserSession, fieldsToInclude);

                // iterate through the respondents. If search query not like results throw the result away.
                List<Respondent> toRemove = new List<Respondent>();
                for (int i = 0; i < respondents.Count; i++)
                {
                    if (!respondents[i].EmailAddresses.Any())
                        toRemove.Add(respondents[i]);
                    else
                    {
                        bool checkSingleEmail = false;
                        bool checkAllEmails = false;
                        for (int j = 0; j < respondents[i].EmailAddresses.Count; j++)
                        {
                            checkSingleEmail = respondents[i].EmailAddresses[j].Address.ToString().Contains(query);

                            if (checkSingleEmail == true)
                                checkAllEmails = true;

                            if (respondents[i].EmailAddresses.Count == 1 && j == 0 && checkAllEmails == false)
                                toRemove.Add(respondents[i]);
                            else if (checkAllEmails == false && j+1 == respondents[i].EmailAddresses.Count)
                                toRemove.Add(respondents[i]);
                        }
                    }
                }

                foreach (var respRemove in toRemove)
                {
                    respondents.Remove(respRemove);
                }

例如,最后一项可能在索引4处开始。但是如果删除索引3,那么它现在位于索引3并且索引4不存在。

答案 2 :(得分:2)

你需要改变:

respondents.RemoveAt(respRemove);

respondents.Remove(respRemove);

这是由于RemoveAt()绑定到索引,并且该项已被删除,该命令变为无效。

答案 3 :(得分:2)

在删除之前反转toRemove的顺序。然后在每次删除后保留其余项目的索引。

toRemove.Reverse();

foreach (int respRemove in toRemove)
{
    respondents.RemoveAt(respRemove);
}

要注意的另一件事是,如果我被多次添加:

    for (int j = 0; j < respondents[i].EmailAddresses.Count; j++)
    {
       ...
            toRemove.Add(i);

不要让我多次加入toRemove。