2011-10-24 4 views
5

quiero hacer algo como esto:¿Puedo usar el operador de fusión en enteros para encadenar CompareTo?

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

esto no funciona como está escrito; ¿Hay alguna solución mínima para que funcione? Básicamente quiero 0 para encadenar hasta que sea distinto de cero (o al final de la cadena).

+0

No sé la respuesta a su pregunta, pero si tres valores se pueden utilizar para determinar el valor de retorno, es posible que desee considerar el rediseño de su clase. –

+0

@DJ 'CompareTo' está relacionado con la clasificación; eso es bastante común, en realidad, por ejemplo, ordenar por apellido, si es lo mismo, ordenar por Nombre, y si aún es igual, ordenar por algún identificador único (por ejemplo, id de la base de datos). –

+0

@Marc Interesante, no he estado expuesto a esto antes. Veo que CompareTo es parte de la clase de IComparable. Tendré que leer más para tener algo de perspectiva. Gracias –

Respuesta

2

no soportados por el lenguaje . Pero se puede escribir un pequeño ayudante de la siguiente manera:

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. Soluciones como esta ilustran cuánto apesta que no podamos tener funciones globales. –

+0

Uno siempre podría ponerlo en una función de extensión si se usa mucho, etc. – driis

+0

¿Una extensión en qué? Int32? ¿Es eso posible? –

2

No, básicamente, pero estaría bien si lo hiciera (IIRC, Jon mencionó una idea similar en C# en profundidad). Probablemente se podría encadenar condicionales, pero tiendo a utilizar:

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

En realidad no, ?? sólo funciona para los valores nulos (tipos de referencia o estructuras anulables)

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; 
Cuestiones relacionadas