2012-03-08 20 views
14

Estoy sobrecargando el menor operador en C# y me pregunto si esto debe verificar si es nulo. A continuación puede encontrar un ejemplo:necesita el operador de sobrecarga <y la verificación nula

public static bool operator <(MyClass x, MyClass y) 
{ 
    if (x == null && y == null) 
    { 
    return false; 
    } 
    if (x == null) 
    { 
    return true; //false? 
    } 
    if (y == null) 
    { 
    return false; //true? 
    } 
    return x.Value < y.Value; 
} 

o esto es correcto:

public static bool operator <(MyClass x, MyClass y) 
{ 
    return x.Value < y.Value; 
} 

que no encontramos ninguna instrucción sobre esto. Pero tal vez me perdí algo.

Respuesta

12

La respuesta depende del patrón de uso previsto. Si planea tener valores nulos en la combinación, y le gustaría considerar que los valores null son menores que los valores no nulos, entonces su implementación es correcta; si desea considerar que los valores null son mayores que los objetos que no son nulos, los valores de retorno comentado (false y true) deben usarse en su lugar. Si no planea permitir nulos en la mezcla, lanzar un ArgumentNullException o permitir NullReferenceException sería la opción correcta.

+1

Lanzar hijos 'ArgumentNullException', nunca lanzar una' NullReferenceException' intencional. – Dagrooms

+0

Es la diferencia entre "Quise hacer esto" y "¡Uy!" – Dagrooms

1

Un operador personalizado es poco más que un método estático. Además, los operadores en general no deberían lanzar excepciones. Lo que significa que necesita esos chequeos nulos si MyClass es un tipo de referencia.

Por cierto, es convencional que nulls sea menor que nulls, lo que hace que su implementación propuesta sea idiomática.

+0

¿cómo puede ser nulo el primer parámetro? – vulkanino

+0

O simplemente deja que el sistema se lance, no hay daño en eso (excepto que la excepción es un poco menos apropiada). –

+0

@vulkanino: El primer parámetro puede ser nulo ya que el operador se implementa como un método estático. – Ani

2

Personalmente me lanzo una ArgumentNullException si bien x o y son null, que debe ser una circunstancia excepcional.

+5

'NullReferenceException' no debe arrojarse desde el código de usuario, significa que hay un error de programación. Use 'ArgumentNullException' en su lugar. – asawyer

+0

@asawyer Acaba de editar;) – mdm

+0

@asawyer 'ArgumentNullException' también indica un error de programación. No estoy seguro de haber tenido ambas fue una decisión tan inteligente del marco. –

4

Ambos enfoques son correctos (para diferentes valores de correcto).

Si x o y son nulos y tienen un significado válido en su caso, entonces vaya con el primer acercamiento.

Si es poco probable que x y y sean nulos, vaya con el segundo y deje que las excepciones se propaguen al código de llamada para su manejo.

-1
  1. que es una mala idea para los operadores de sobrecarga en las clases. Sin embargo, está bien para las estructuras.

  2. Si decide sobrecargar un operador en una clase, tendrá que:
    a. Incluya la verificación nula en su lógica
    b. Lanzar excepciones cuando se pasa null en
    c. Hacer el registro no nulo y permitir NullReferenceExceptions (malo)

Básicamente, es una mala idea para sobrecargar un operador en una clase. Convertiría tu clase en una estructura, o simplemente implementaría una interfaz como IComparable<T>/IEquatable<T> que tiene directrices cuando se usan valores nulos en las comparaciones.

+0

No estoy de acuerdo con eso, a menudo tiene sentido tener clases de valor, en particular debido a que la guía relevante (útil) en .NET dice" si tiene dudas, escriba una clase ". –

+0

Es una peor idea operadores de sobrecarga para una clase. Una estructura es un valor que se puede comparar con otros valores. Una clase es una referencia y no debe tratarse como una estructura. Todavía no veo la necesidad de sobrecargar un operador para una clase (como opuesto a una estructura) alguna vez. –

+1

ejemplo estándar: Clase compleja. ¿No sobrecargaría los operadores? – vulkanino