using System.Runtime.InteropServices;
namespace System.Collections.Generic {
- [CLSCompliant(false)]
- public abstract class Comparer<T> : IComparer<T>, System.Collections.IKeyComparer,
- System.Collections.IComparer, System.Collections.IHashCodeProvider {
-
- public Comparer () {} /* workaround 60438 by not having a protected ctor */
- public abstract int Compare (T x, T y);
- public virtual bool Equals (T x, T y)
- {
- return Compare (x, y) == 0;
- }
- public virtual int GetHashCode (T obj)
+ [Serializable]
+ public abstract class Comparer<T> : IComparer<T>, System.Collections.IComparer {
+
+ static Comparer ()
{
- if (obj == null)
- throw new ArgumentNullException ();
- return obj.GetHashCode ();
+ if (typeof (IComparable<T>).IsAssignableFrom (typeof (T)))
+ _default = (Comparer<T>) Activator.CreateInstance (typeof (IComparableOfTComparer <>).MakeGenericType (typeof (T)));
+ else
+ _default = new DefaultComparer ();
}
+
+
+ public abstract int Compare (T x, T y);
- static DefaultComparer <T> _default;
+ static readonly Comparer <T> _default;
- [MonoTODO ("This is going to make a really slow comparer. We need to speed this up if T : ICompareable<T> create a class with a where clause of T : ICompareable <T>")]
- public static Comparer<T> Default {
+ public static Comparer <T> Default {
get {
- if (_default != null)
- return _default;
- return _default = new DefaultComparer<T> ();
+ return _default;
}
}
throw new ArgumentException ();
}
- bool System.Collections.IKeyComparer.Equals (object x, object y)
- {
- if (x == y)
- return true;
-
- if (x == null || y == null)
- return false;
-
- if (x is T && y is T)
- return Equals ((T) x, (T) y);
-
- throw new ArgumentException ();
- }
-
- int System.Collections.IHashCodeProvider.GetHashCode (object obj)
- {
- if (obj == null)
- throw new ArgumentNullException ();
- if (obj is T)
- return GetHashCode ((T) obj);
-
- throw new ArgumentException ();
- }
-
- class DefaultComparer<T> : Comparer<T> {
+ class DefaultComparer : Comparer<T> {
public override int Compare (T x, T y)
{
else
throw new ArgumentException ("does not implement right interface");
}
+ }
+ }
- public override bool Equals (T x, T y)
- {
- return Object.Equals (x, y);
- }
+ class IComparableOfTComparer <T> : Comparer <T> where T : IComparable<T> {
+ public override int Compare (T x, T y)
+ {
+ // `null' is less than any other ref type
+ if (x == null)
+ return y == null ? 0 : -1;
+ else if (y == null)
+ return 1;
+
+ return x.CompareTo (y);
}
}