2013-10-24 46 views
2

我不断收到一个索引超出范围例外。不能是非负数,并且小于集合的大小。指数超出范围。必须是非负的错误

问题是我检查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); 
} 

回答

6

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

foreach (var respRemove in toRemove.OrderByDesc(r => r).ToList()) 
{ 
    respondents.RemoveAt(respRemove); 
} 
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不存在。

+0

+1 oskar,你说的跟我自己差不多:) –

+0

当我尝试使用上面的respRemove foreach时,我收到repondents.Remove(respRemove)的错误。最好的重载方法匹配有一些无效的参数。 – allencoded

+0

@allencoded那么受访者的类型是什么? –

2

你需要改变:

respondents.RemoveAt(respRemove); 

respondents.Remove(respRemove); 

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

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

不要让我被添加到文档,删除不止一次。

+0

例如,受访者中的索引4(如果有5个项目)将不存在,即使您在索引0处首先删除 –

+0

这就是为什么您删除4,然后是0. –

+0

真实,愚蠢的我...... –

相关问题