Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't IEnumerable<T>.Max constrain T to be IComparable?

Tags:

c#

linq

generics

If one calls the .Max() extension method on an IEnumerable<T>, and the objects within do not implement IComparable, one gets System.ArgumentException: At least one object must implement IComparable.

Why don't Max and similar methods constrain T to implement IComparable, so that this problem can be caught at compile time instead of at run time?

like image 763
Matt Howells Avatar asked Jul 24 '09 09:07

Matt Howells


2 Answers

Comparisons are... fun. Firstly, you've got a choice of IComparable<T> or IComparable - which would you choose? Currently (via Comparer<T>.Default) it supports both, but there is no "this or that" generic constraint.

Then you get the issue of Nullable<T>; this has "lifted" comparisons, so whether it is comparable or not depends on the T; but again, Comparer<T>.Default deals with this for us (Nullable<T> implements neither IComparable nor IComparable<T>).

Plus; it saves on generic constraint propagation; as soon as you have a constraint like this in library code, it quickly infects all the upstream calling code, making it a hard slog.

like image 147
Marc Gravell Avatar answered Sep 20 '22 22:09

Marc Gravell


I guess because it's more flexible. For example, you may have an IEnumerable<object> which happens to contain strings, in which case Max() can be called quite safely on it, despite the fact that the type Object does not implement IComparable.

like image 25
Matt Howells Avatar answered Sep 23 '22 22:09

Matt Howells