c# - linq索引越界

标签 c# linq list indexoutofboundsexception

在我 friend 的代码中,他有一个List:

 List<int> listOfIds = new List<int>();

然后我使用AddRange()向其中添加一个int集合:

   listOfIds.AddRange(this._employeeList
                       .Where(r => r.EmployeeID != null)
                       .Select(r => r.EmployeeID != null ? r.EmployeeID.Value : 0));

但是,在日志中,它说:

 System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at System.Collections.Generic.List`1.Enumerator.MoveNext()
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Collections.Generic.List`1.InsertRange(Int32 index, IEnumerable`1 collection)
   at the method which called the codes above.....

我不太确定为什么会发生这种情况。我很确定上面的代码发生了这个错误,但我似乎无法理解为什么会出现 IndexOutofRangeException

你能帮我指出是什么原因导致的吗?

更新:

我错了。我很抱歉。该方法不使用多线程。但是,调用此方法的另一种方法是使用 Parallel.Foreach,这意味着多线程。当 _employeeList 被用作 AddRange() 的源时,另一个线程可能也在修改它。因此,addrange() 不是线程安全的答案是合理的。非常感谢你们。

最佳答案

很难说出更具体的想法,但这可能会起作用。

AddRange 不是线程安全的。尝试使用锁定原语来添加许多项目。声明:

private static object mutex = new object();

使用

lock(mutex)
{
    listOfIds.AddRange( /* code goes here */ )
}

反编译AddRange后发现

public void AddRange(IEnumerable<T> collection)
{
  this.InsertRange(this._size, collection);
}

InsertRange 的内容,您可以在堆栈跟踪中看到:

  ...
  ICollection<T> collection1 = collection as ICollection<T>;
  if (collection1 != null)
  {
     ...
  }
  else
  {
    foreach (T obj in collection)
      this.Insert(index++, obj);
  }

换句话说 - 它迭代序列并尝试使用增量索引逐项添加。这应该不会出错,不是吗? List.cs 中的 845 行由 dotPeek 反编译。所以我不会相信堆栈跟踪,除非我会看到整个堆栈跟踪。

关于c# - linq索引越界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14260658/

相关文章:

file - 如何将文件转换为 tcl 列表?

c# - 我如何在 Linq 中分组?

c# - 使用嵌套选择 LINQ 循环数组

python - 将列表中的每三个项目组合在一起 - Python

python - 将大写字母移动到字符串前面并将小写字母大写的函数?

c# - 使用 Linq 在 Epplus 工作表中选择分组的最大值和最小值

c# - 单元测试静态实用程序类

c# - 在您的项目中是否有任何您认为必不可少的 Action 过滤器?

c# - RenderControl 方法不呈现自关闭标签

c# - 如何使用 linQ 访问列表中的上一个项目?