2011-10-24 1 views
5

voglio fare qualcosa di simile:Posso utilizzare l'operatore di coalesce su numeri interi per concatenare CompareTo?

public override int CompareTo (Foo rhs) 
{ 
    return Bar.CompareTo(rhs.Bar) ?? 
      Baz.CompareTo(rhs.Baz) ?? 
      Fuz.CompareTo(rhs.Fuz) ?? 0; 
} 

Questo non funziona come scritto; c'è qualche soluzione minima per farlo funzionare? Fondamentalmente voglio 0 a catena fino a non-zero (o alla fine della catena).

+0

Non conosco la risposta alla tua domanda, ma se tre valori possono essere utilizzati per determinare il valore di ritorno, si potrebbe prendere in considerazione riprogettare la vostra classe. –

+0

@DJ 'CompareTo' è relativo all'ordinamento; questo è abbastanza comune, in realtà - per esempio, ordina per cognome - se è lo stesso, quindi ordina per FirstName, quindi se è ancora uguale, ordina per qualche identificatore univoco (id del database, per esempio). –

+0

@Marc Interessante, non sono stato esposto a questo prima. Vedo che CompareTo fa parte della classe IComparable. Dovrò leggere di più per avere una prospettiva. Grazie –

risposta

2

non supportati dal linguaggio . Ma si può scrivere un piccolo aiuto come questo:

public override int CompareTo (Foo rhs) 
{ 
    return FirstNonZeroValue(
     () => Bar.CompareTo(rhs.Bar), 
     () => Baz.CompareTo(rhs.Baz), 
     () => Fuz.CompareTo(rhs.Fuz)); 
} 

private int FirstNonZeroValue(params Func<int>[] comparisons) 
{ 
    return comparisons.Select(x => x()).FirstOrDefault(x => x != 0); 
} 
+0

Ugh. Soluzioni come questa illustrano quanto ci fa schifo che non possiamo avere funzioni globali. –

+0

Si potrebbe sempre inserire una funzione di estensione se utilizzata molto, ecc. – driis

+0

Un'estensione su cosa? Int32? È possibile? –

2

No fondamentalmente, ma sarebbe bello se lo facesse (IIRC, Jon ha menzionato un'idea simile in C# in Profondità). Probabilmente si può concatenare condizionali, ma tendo utilizzare solo per:

int delta = Bar.CompareTo(rhs.Bar); 
if(delta == 0) delta = Baz.CompareTo(rhs.Baz); 
if(delta == 0) delta = Fuz.CompareTo(rhs.Fuz); 
return delta; 
2

Non proprio, ?? funziona solo per valori nulli (tipi di riferimento o le strutture nullable)

int i; 

i = Bar.CompareTo(rhs.Bar); 
if (i != 0) return i; 

i = Baz.CompareTo(rhs.Baz); 
if (i != 0) return i; 

i = Fuz.CompareTo(rhs.Fuz); 
if (i != 0) return i; 

return 0;