È possibile scrivere il proprio comparatore che delega a uno esistente per non null, ma alla fine ordina sempre valori null. Qualcosa di simile a questo:
public class NullsLastComparer<T> : IComparer<T>
{
private readonly IComparer<T> proxy;
public NullsLastComparer(IComparer<T> proxy)
{
this.proxy = proxy;
}
public override int Compare(T first, T second)
{
if (first == null && second == null)
{
return 0;
}
if (first == null)
{
return 1;
}
if (second == null)
{
return -1;
}
return proxy.Compare(first, second);
}
}
EDIT: Alcuni problemi con questo approccio:
In primo luogo, esso non gioca bene con i tipi anonimi; potrebbe essere necessario un metodo di estensione separato per farlo funzionare bene. Oppure usa la risposta di Ken :)
Ancora più importante, viola il contratto IComparer<T>
, che specifica che i valori nulli devono essere i primi. Ora personalmente, penso che questo sia un errore nella specifica IComparer<T>
- dovrebbe forse definire che il comparatore dovrebbe gestire null, ma dovrebbe non specificare se vengono prima o l'ultima ... fa requisiti come questo (quale sono perfettamente ragionevoli) impossibili da adempiere con la massima chiarezza possibile, e ha ogni genere di conseguenze imbarazzanti per cose come un confronto inverso. Ci si aspetterebbe che una cosa del genere invertisse completamente l'ordine, ma secondo le specifiche dovrebbe comunque mantenere i valori nulli all'inizio :(
Non penso di aver visto alcuna implementazione di ordinamento .NET che effettivamente si basa su questo, ma è sicuramente vale la pena di essere a conoscenza di
fonte
2010-07-02 06:30:46
Non si tratta di una violazione del contratto con le implementazioni di ordinamento .NET? Ho pensato di aver letto da qualche parte che i metodi di ordinamento possono presupporre che i null vengano prima ... o ...? –
@Lasse: Si tratta di una violazione dell'interfaccia 'IComparer, sì - modificherò il mio post per menzionarlo. –
Sì, ma da quello che ricordo da quando ho letto su questo, sembrava che i metodi di ordinamento potessero prendere scorciatoie a causa di questo contratto, e quindi in realtà non chiamare il metodo di comparazione per alcuni casi, poiché "sapeva" già quale risultato sta per essere. In altre parole, non produrrà risultati funky in alcuni casi? –