2012-03-08 13 views
14

Sto sovraccaricando l'operatore lessthan in C# e mi chiedo se questo debba verificare se è nullo. Qui di seguito potete trovare un esempio:necessita di overload operator <e controllo nullo

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 si tratta di corretta:

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

mi hanno ragione't trovare alcuna istruzione su questo. Ma forse mi sono perso qualcosa.

risposta

12

La risposta dipende dal modello di utilizzo previsto. Se si prevede di avere valori nulli nel mix e si desidera considerare i valori null inferiori a valori non nulli, l'implementazione è corretta; se si desidera considerare i valori null superiori a quelli non nulli, è necessario utilizzare i valori restituiti commentati (false e true). Se non si prevede di consentire i null nel mix, lanciare un ArgumentNullException o consentire NullReferenceException sarebbe la scelta giusta.

+1

Lancia i bambini 'ArgumentNullException', non lanciare mai una' NullReferenceException 'intenzionale. – Dagrooms

+0

È la differenza tra "intendevo fare questo" e "oops"." – Dagrooms

1

Un operatore personalizzato è poco più di un metodo statico. Inoltre, gli operatori dei generali non dovrebbero normalmente lanciare eccezioni. Il che significa che hai bisogno di quei controlli null se MyClass è un tipo di riferimento.

A proposito, è normale che nulls sia inferiore a non nulls, il che rende l'implementazione proposta idiomatica.

+0

come può essere nullo il primo parametro? – vulkanino

+0

O lasci semplicemente che il sistema lanci, nessun danno (tranne che l'eccezione è leggermente meno appropriata). –

+0

@vulkanino: il primo parametro può essere nullo poiché l'operatore è implementato come metodo statico. – Ani

2

Personalmente vorrei gettare un ArgumentNullException se uno o xy sono null, che dovrebbe essere una circostanza eccezionale.

+5

'NullReferenceException' non dovrebbe essere gettato dal codice utente, significa che c'è un bug di programmazione. Usa invece 'ArgumentNullException'. – asawyer

+0

@asawyer Appena modificato;) – mdm

+0

@asawyer 'ArgumentNullException' indica anche un bug di programmazione. Non sono sicuro che entrambi siano stati una decisione così intelligente del framework. –

4

Entrambi gli approcci sono corretti (per diversi valori di corretto).

Se x o sono probabilmente nulli e questo ha un significato valido nel tuo caso, quindi vai con il primo approccio.

Se è improbabile che il valore x e sia nullo, passare al secondo e lasciare propagare eventuali eccezioni al codice chiamante per la gestione.

-1
  1. E 'una cattiva idea di sovraccaricare gli operatori sulle classi. Però va bene per le strutture.

  2. Se si decide di sovraccaricare un operatore in una classe, sarà necessario:
    a. Includi null check nella tua logica
    b. Genera eccezioni quando viene passato nulla in
    c. Fare controllo non nullo e consentire NullReferenceExceptions (cattivi)

In sostanza, si tratta di una cattiva idea di sovraccaricare un operatore su una classe. Trasformerei la tua classe in una struttura, o semplicemente implementare un'interfaccia come IComparable<T>/IEquatable<T> che ha delle linee guida quando i valori nulli sono usati nei confronti.

+0

Non sono d'accordo: spesso ha senso avere classi di valore, in particolare poiché la pertinente (utile) linea guida in .NET dice" se sei in dubbio, scrivi una classe ". –

+0

È un'idea peggiore operatori di overload per una classe Una struct è un valore che può essere paragonato ad altri valori Una classe è un riferimento e non deve essere trattata come una struct. Devo ancora vedere la necessità di sovraccaricare un operatore per una classe (come –

+1

esempio standard: classe complessa Non sovraccaricheresti gli operatori? – vulkanino

Problemi correlati