为什么肯定会在运行时失败的List.Sort会编译?

时间:2018-08-24 21:55:50

标签: c#

我正在四处寻找如果创建List的对象而不实现比较运算符并调用.Sort()会出现什么编译器错误。 我很惊讶它编译后在运行时崩溃:

[System.ArgumentException: At least one object must implement IComparable.]
   at System.Collections.Comparer.Compare(Object a, Object b)
   at System.Collections.Generic.ObjectComparer`1.Compare(T x, T y)
   at System.Collections.Generic.ArraySortHelper`1.InsertionSort(T[] keys, Int32 lo, Int32 hi, IComparer`1 comparer)
   at System.Collections.Generic.ArraySortHelper`1.IntroSort(T[] keys, Int32 lo, Int32 hi, Int32 depthLimit, IComparer`1 comparer)
   at System.Collections.Generic.ArraySortHelper`1.IntrospectiveSort(T[] keys, Int32 left, Int32 length, IComparer`1 comparer)
   at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
[System.InvalidOperationException: Failed to compare two elements in the array.]
   at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
   at System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer`1 comparer)
   at System.Collections.Generic.List`1.Sort(Int32 index, Int32 count, IComparer`1 comparer)
   at System.Collections.Generic.List`1.Sort()
   at Example.Main() :line 49

C#编译器允许此代码进行编译的原因是什么?

注意:我希望很明显,我不是在问如何修正我的代码,这很简单,我在问为什么要编译此错误代码。

1 个答案:

答案 0 :(得分:2)

您可以通过实现IComparer接口来提供一个自写的比较器。而如果您不这样做,它将寻找Comparer<T>.Default获得一个。因此,从技术上讲,可以在对象未实现Sort()的列表上调用Icomparable,因为随后将使用Comparer<T>.Default。这意味着您可以在任何列表上调用Sort(),而不必限制值必须实现IComparable。但是,这也意味着Comparer<T>.Default源代码在内部使用该比较器时,您无法在编译时检查Sort()处是否有比较器。