2010-06-09 9 views
16

quando provo a sovraccaricare l'operatore == e! = In C#, e sovrascrivo Equal come raccomandato, ho trovato Non ho modo di distinguere un oggetto normale e null. Ad esempio, ho definito un Complesso di classe.overload == (e! =, Ovviamente) operatore, posso bypassare == per determinare se l'oggetto è nullo

public static bool operator ==(Complex lhs, Complex rhs) 
{ 
    return lhs.Equals(rhs); 
} 

public static bool operator !=(Complex lhs, Complex rhs) 
{ 
    return !lhs.Equals(rhs); 
} 

public override bool Equals(object obj) 
{ 
    if (obj is Complex) 
    { 
     return (((Complex)obj).Real == this.Real && 
        ((Complex)obj).Imaginary == this.Imaginary); 
    } 
    else 
    { 
     return false; 
    } 
} 

Ma quando voglio usare

if (temp == null) 

quando la temperatura è davvero nulla, qualche eccezione accade. E non posso usare == per determinare se lhs è nullo, il che causerà loop infinito.

Cosa devo fare in questa situazione.

Un modo in cui riesco a pensare è per noi qualcosa come Class.Equal (oggetto, oggetto) (se esiste) per ignorare == quando eseguo il controllo.

Qual è il modo normale di risolvere il problema?

Grazie.

+0

possibile duplicato di [Come posso verificare la presenza di null in un sovraccarico dell'operatore '==' senza ricorsione infinita?] (Http://stackoverflow.com/questions/73713/how-do-i-check-for-nulls -in-un-operatore-sovraccarico-senza-infinito-ricorsione) – Sam

risposta

10

si consiglia di utilizzare il metodo static Equals nei sovraccarichi operatore (che chiamerà l'istanza Equals metodo):

public static bool operator ==(Complex lhs, Complex rhs) 
{ 
    return Equals(lhs, rhs); 
} 

public static bool operator !=(Complex lhs, Complex rhs) 
{ 
    return !Equals(lhs, rhs); 
} 

Nota: Si può anche verificare la presenza di null nel metodo Equals.

È anche possibile leggere il Object.Equals Topic on MSDN, che è una grande fonte di campioni.

+0

Grazie, funziona, ma non sono sicuro del perché. E, perché l'oggetto può essere omesso in Object.Equals()? E non ho trovato il motivo per cui questo può prevenire il problema nullo in MSDN. (Verifica prima null?) – LLS

+1

Non è necessario il prefisso della classe Object perché Complesso eredita da Object; Complesso vedi i metodi statici dell'oggetto. Non conosco i componenti interni del metodo Equals statico, ma probabilmente verifica il null prima di chiamare il metodo Equals dell'istanza. –

+1

Se lhs non è nullo, il valore statico Equals chiama il metodo di istanza Equals su lhs. Se lhs è null Equals confronta i riferimenti di lhs e rhs. –

14

È possibile utilizzare il seguente nella parte superiore del vostro Equals sovrascrivono:

if (Object.ReferenceEquals(obj, null)) 
    return false; 

L'eccezione si stanno ottenendo è probabilmente uno StackOverflowException perché il vostro operatore == causerà una ricorsione infinita.

EDIT:

Se Complex è una struttura non dovreste avere problemi con NullReferenceExceptions. ! Se Complex è una classe è possibile modificare l'implementazione del == e operatore = sovraccarichi per evitare l'eccezione (Laurent Etiemble già fatto notare nella sua risposta):

public static bool operator ==(Complex lhs, Complex rhs) 
{ 
    return Equals(lhs, rhs); 
} 

public static bool operator !=(Complex lhs, Complex rhs) 
{ 
    return !Equals(lhs, rhs); 
} 
+0

In realtà è il riferimento oggetto non impostato su un'istanza di un oggetto. Dovrebbe funzionare, grazie. :) – LLS

+0

L'eccezione esiste ancora, poiché si tenta di chiamare null.Equals(). – LLS

+0

Considererei la creazione di una struct Complex anziché di una classe. –

0

C'è un approccio migliore quindi utilizzando gli operatori is e cast:

Complex c = obj as Complex; 
return (c != null) && (c.Real == this.Real) && (c.Imaginary == this.Imaginary); 

Qui è un test rapido preoccupante Equals operatore override e il confronto con null:

class Complex 
{ 
    public override bool Equals(object obj) 
    { 
     if (obj is Complex) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
} 

debug non passo in Corpo dell'operatore:

var b = (new Complex() == new Complex()); 
+0

Grazie, ma sembra che c! = Null causerà loop infinito. – LLS

+0

@LLS: Davvero? Interessante. Non è sicuro che il confronto con 'null' userà l'operatore di confronto' object'. Ma forse .. – abatishchev

+0

@LLS: Vedi il mio post aggiornato – abatishchev

2
public static bool operator ==(Complex lhs, Complex rhs) 
{ 
    if (Object.ReferenceEquals(lhs, null)) 
    { 
     return Object.ReferenceEquals(rhs, null); 
    } 

    return lhs.Equals(rhs); 
} 

public static bool operator !=(Complex lhs, Complex rhs) 
{ 
    return !(lhs == rhs); 
} 

unit test Poor dell'uomo

Action<Complex, Complex> tester = (left, right) => 
{ 
    Console.WriteLine(left == right); 
    Console.WriteLine(left != right); 
    Console.WriteLine(left == null); 
    Console.WriteLine(left != null); 
    Console.WriteLine("---"); 
}; 

tester(new Complex(), new Complex()); 
tester(null, new Complex()); 
tester(null, null); 
tester(new Complex(), null); 
+0

Grazie mille. È facile da capire – LLS

0

penso che si shoud prova per nulla nella realizzazione operatore ==. Altrimenti, quando lhs è nullo, chiamereste Complex (null) .Equals (Non so per C#, ma in Java questa sarebbe un'eccezione Nullpointer)

Per provare per null, suggerisco qualcosa come:

if (null == lhs && null == rhs) return true 
else if (null == lhs) return false 
else return lhs.Equals(rhs); 

Quindi Object.Equals verrà chiamato per tutti i confronti == sopra.

+0

Si ottiene una chiamata ricorsiva per l'operatore ==. –

+0

Ok, interessante. Semplicemente curioso, come viene chiamato quell'operatore == (Complesso, Complesso), quando provo per null == lhs? In che modo il compilatore decide che "null" è di tipo Complex? – nang

Problemi correlati