NoSenseEtAl
NoSenseEtAl

Reputation: 30108

Why does List.Sort that will for sure fail at runtime compiles?

I was playing around to see what compiler error will I get if I create List of objects that do not implement comparison operators and call .Sort() . I was surprised that it compiled and then crashed at runtime:

[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

What is the reason why C# compiler allow this code to compile?

note: I hope it is clear that I am not asking how to fix my code, it is trivial, I am asking about why this buggy code is compiling.

Upvotes: 0

Views: 340

Answers (1)

Progman
Progman

Reputation: 19555

You can provide a self written comparer by implementing the IComparer interface. And when you don't, it will look for Comparer<T>.Default to get one. So technically it can be fine to call Sort() on a list where Icomparable isn't implemented by the objects, because Comparer<T>.Default will be used then. This means you can call Sort() on any list without the restriction that the values must implement IComparable. But this also means you cannot check at compile time if there will be a comparer available at Comparer<T>.Default at the time when it is is used internally by the Sort() source code.

Upvotes: 2

Related Questions