2

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

问题是当我检查toRemove计数低于受访者时。那么这个错误是怎么发生的呢?如果有 5 个respondents并且toRemove只有 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

4 回答 4

6

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

foreach (var respRemove in toRemove.OrderByDesc(r => r).ToList())
{
    respondents.RemoveAt(respRemove);
}
于 2013-10-24T13:50:46.777 回答
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 不存在。

于 2013-10-24T13:47:30.427 回答
2

你需要改变:

respondents.RemoveAt(respRemove);

respondents.Remove(respRemove);

这是由于与RemoveAt()索引相关联,并且由于该项目已被删除,该命令变得无效。

于 2013-10-24T13:50:55.750 回答
2

在删除之前颠倒 toRemove 的顺序。然后在每次删除后保留剩余项目的索引。

toRemove.Reverse();

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

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

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

不要让我多次添加到 toRemove。

于 2013-10-24T13:51:10.087 回答