Bene, è possibile controllare la fonte di riferimento e see for yourself quello che fa.
public static Comparer<T> Default {
get {
Contract.Ensures(Contract.Result<Comparer<T>>() != null);
Comparer<T> comparer = defaultComparer;
if (comparer == null) {
comparer = CreateComparer();
defaultComparer = comparer;
}
return comparer;
}
}
private static Comparer<T> CreateComparer() {
RuntimeType t = (RuntimeType)typeof(T);
// If T implements IComparable<T> return a GenericComparer<T>
#if FEATURE_LEGACYNETCF
//(SNITP)
#endif
if (typeof(IComparable<T>).IsAssignableFrom(t)) {
return (Comparer<T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer<int>), t);
}
// If T is a Nullable<U> where U implements IComparable<U> return a NullableComparer<U>
if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) {
RuntimeType u = (RuntimeType)t.GetGenericArguments()[0];
if (typeof(IComparable<>).MakeGenericType(u).IsAssignableFrom(u)) {
return (Comparer<T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer<int>), u);
}
}
// Otherwise return an ObjectComparer<T>
return new ObjectComparer<T>();
}
Allora, cosa che fa è controlla se il tipo implementa IComparable<T>
, se lo fa utilizza l'operatore di confronto costruito in funzione del tipo (l'elenco degli oggetti che sono i tipi numerici avrebbero seguito questo ramo). Quindi esegue di nuovo lo stesso controllo nel caso in cui il tipo sia Nullable<ICompareable<T>>
. Se anche questo non funziona, utilizza lo ObjectComparer
che utilizza Comparer.Default
.
Here is the Compare code per Comparer.Default
public int Compare(Object a, Object b) {
if (a == b) return 0;
if (a == null) return -1;
if (b == null) return 1;
if (m_compareInfo != null) {
String sa = a as String;
String sb = b as String;
if (sa != null && sb != null)
return m_compareInfo.Compare(sa, sb);
}
IComparable ia = a as IComparable;
if (ia != null)
return ia.CompareTo(b);
IComparable ib = b as IComparable;
if (ib != null)
return -ib.CompareTo(a);
throw new ArgumentException(Environment.GetResourceString("Argument_ImplementIComparable"));
}
Come si può vedere controlla se a
o b
implementa IComparable
e se non farlo genera un'eccezione.
fonte
2015-08-11 22:23:55
Questo post di Jon Skeet può essere utile per te http://codeblog.jonskeet.uk/2011/01/05/reimplementing-linq-to-objects-part-26b-orderby-descending-thenby-descending/ . In realtà, l'intera serie di EduLinq è piacevole da leggere e comprendere una serie di concetti. –