行为不一致:在foreach循环中调用时,List <T> .Sort方法中不会抛出异常

Dmi*_*try 8 c# base-class-library

我们知道,如果我们在foreach循环中更改集合,则抛出以下异常:

InvalidOperationException:Collection已被修改; 枚举操作可能无法执行.

但是有一种行为方式不同:List<T>.Sort(Comparison<T>).

例如(dotnetfiddle.net):

List<int> list = new List<int> { 2, 1 } ;
foreach (int i in list)
{
    //list.Sort(Comparer<int>.Default);         // InvalidOperationException
    //list.Sort();                              // InvalidOperationException
    list.Sort((a, b) => a.CompareTo(b));        // No exception

    Console.WriteLine(i);
}
Run Code Online (Sandbox Code Playgroud)

根据referencesource.microsoft.com,我们可以看到这个特定方法没有版本增量,而上面的方法中有一个:

public void Sort(int index, int count, IComparer<T> comparer) {
    ...
    _version++;
}
Run Code Online (Sandbox Code Playgroud)

在修改列表的所有其他方法中,版本也会增加.

我的问题是:

  1. 这是一个错误吗?或者有这种行为的原因?
  2. 如果它是一个错误,为什么它多年没有修复?

我记得我在大约8 - 9年前将这个错误报告发布给微软,但它被拒绝了.现在我再也找不到了.

Aka*_*ava 2

这是一个错误,这就是为什么它在最新的源代码中得到修复。

https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/Collections/Generic/List.cs#L986

    public void Sort(Comparison<T> comparison) {
        if( comparison == null) {
            ThrowHelper.ThrowArgumentNullException(ExceptionArgument.comparison);
        }
        Contract.EndContractBlock();

        if (_size > 1) {
            ArraySortHelper<T>.Sort(_items, 0, _size, comparison);
        }
        _version++;
    }
Run Code Online (Sandbox Code Playgroud)

可能会有很多类似的错误,除非有人报告并且被认为风险很大,否则它们会保留下来,因为它们不是优先事项。

别担心,在 中也有类似的错误List.ForEach,不会抛出修改的异常,我确实报告了它,但他们拒绝了,但在后续版本中它被修复了。

  • 好的。顺便说一句,看来 OP 是提交修复的人 (Y) (2认同)