2016-01-12 24 views
19

Qualcuno può spiegarmi cosa significa questo sovraccarico?Che cosa significa questo sovraccarico?

public static bool operator ==(Shop lhs, Shop rhs) 
{ 
    if (Object.ReferenceEquals(lhs, null)) 
    { 
     if (Object.ReferenceEquals(rhs, null)) 
     { 
      return true; 
     } 
     return false; 
    } 

    return lhs.Equals(rhs); 
} 

Non ho mai visto Object.ReferenceEquals in sovraccarico

+5

'oggetto. ReferenceEquals' controlla se i riferimenti sono uguali ...;) - In altre parole, controlla se l'oggetto è lo * stesso oggetto *, in termini di m fisico indirizzo di memoria. – Rob

+0

Possibile duplicato di [C# .Equaliti(), .ReferenceEquals() e == operatore] (http://stackoverflow.com/questions/3869601/c-sharp-equals-referenceequals-and-operator) – Rohit

+4

Dal momento = l'operatore della classe Shop è sovraccarico, il codice evita di usarlo per testare i parametri per riferimento null. if (lhs == null) causerebbe una ricorsione infinita e l'app si arresterebbe semplicemente con un'eccezione di overflow dello stack. –

risposta

37

Questo sovraccarico è stato destinato per confrontare due istanze di Shop. Utilizza Object.ReferenceEquals per determinare se una delle istanze è null.
Non è possibile utilizzare lhs == null o rhs == null, poiché ciò invocherebbe nuovamente lo operator == e creerebbe una ricorsione infinita che porta a StackOverflowException.

Se entrambe le istanze sono null, restituisce true (poiché sono uguali).
Se solo un'istanza è null restituisce false (poiché non sono uguali).
Se entrambe le istanze non sono null, restituisce il risultato dell'implementazione Equals di Shop.

+4

potresti anche chiamare '(oggetto) lhs == null' e' (oggetto) rhs == null' per lo stesso effetto – slawekwin

-8

È molto semplice. "NULL" è in realtà un oggetto che risiede in memoria e ha un riferimento e può essere impostato su qualsiasi oggetto che è una sottoclasse della classe "Object" di base.

Quindi, in precedenza, il codice verifica che entrambi gli oggetti "Negozio" siano ugualmente nulli confrontando il loro valore di riferimento con il riferimento oggetto "null", se entrambi sono uguali a null in modo che siano uguali e restituiscano True.

Se solo il primo oggetto è nullo e il secondo non lo è, restituisce falso.

Infine, se il primo oggetto Shop non è null, il codice suppone che il secondo non sia nullo e confronta l'istanza con l'oggetto Shop per verificare che siano uguali.

E il motivo principale per cui utilizziamo questo modo per confrontare un oggetto nullo è perché si ottiene un errore di runtime se si confronta un oggetto nullo o non istanziato, quindi è necessario sovrascrivere l'operatore "==" predefinito in questo modo.

+14

Il tuo involucro è molto fastidioso, inoltre non sono sicuro che _ "'NULL' in realtà sia un oggetto che risiede in memoria "_ è il modo corretto di pensarci – MickyD

+0

Nel caso Negozio essere una struttura (ValueType) Possiamo definirli come Nullable Type (Nullable ) Quindi in questo caso possono essere così. – Waxoft

+0

Infine (se Object.ReferenceEquals (lhs, null) (Check, Does lhs fa riferimento a qualsiasi oggetto e se non fa riferimento a nessun oggetto, allora if è vero. – Waxoft

0

È un operator overload (di ==, non metodo sovraccarico ReferenceEquals) per verificare se due istanze di tipo Shop è di uguale riferimento (cioè, se si riferiscono a lo stesso indirizzo di memoria).

bool result = shop1 == shop2; //shop1 and shop2 are of type Shop 

Quando si dichiara == operatore, vi sarà anche richiesto di sovraccaricare il suo corrispondente (o contro) Operatore !=:

public static bool operator ==(Shop lhs, Shop rhs) { 
    if (Object.ReferenceEquals(lhs, null)) { //Check if the left-hand-side Shop is null 
     if (Object.ReferenceEquals(rhs, null)) { 
      return true; //both are null, equal reference 
     } 
     return false; //lhs is null, but rhs is not (not equal reference) 
    } 
    return lhs.Equals(rhs); //lhs is not null, thus can call .Equals, check if it is Equals to rhs 
} 

public static bool operator !=(Shop lhs, Shop rhs) { //the opposite operator 
    if (Object.ReferenceEquals(lhs, null)) { 
     if (Object.ReferenceEquals(rhs, null)) { 
      return false; 
     } 
     return true; 
    } 
    return !lhs.Equals(rhs); 
} 

Vale anche la pena notare che Object.ReferenceEquals(lhs, null) è usato al posto del lhs == null come il secondo porterà a un altro sovraccarico == chiamato fino al infinite recursion che causa StackOverflowException.

Essi sono utilizzati in questo modo:

Shop shop1 = new Shop(); 
Shop shop2 = new Shop(); 
bool result = shop1 == shop2; //this will return false, since lhs and rhs referring to two different memory address 
shop2 = shop1; 
result = shop1 == shop2; //this will return true, referring to the same memory location 
shop1 = null; 
shop2 = null; 
result = shop1 == shop2; //this will return true, both are null 

Capire questo, si potrebbe anche creare qualcosa di simile:

public struct MyCrazyInt{ //this will reverse the result of + and - 
    private int Value { get; set; } 
    public MyCrazyInt(int value) :this() { 
     Value = value; 
    } 

    public bool Equals(MyCrazyInt otherCrazy) { 
     return this.Value != otherCrazy.Value; //reverse this result 
    } 

    public static MyCrazyInt operator +(MyCrazyInt lhs, MyCrazyInt rhs) { 
     int lhsVal = lhs.Value; 
     int rhsVal = rhs.Value; 
     return new MyCrazyInt(lhsVal - rhsVal); //note that direct lhs-rhs will cause StackOverflow 
    } 

    public static MyCrazyInt operator -(MyCrazyInt lhs, MyCrazyInt rhs) { 
     int lhsVal = lhs.Value; 
     int rhsVal = rhs.Value; 
     return new MyCrazyInt(lhsVal + rhsVal); //note that direct lhs+rhs will cause StackOverflow 
    } 

    public override string ToString() { 
     return Value.ToString(); 
    } 
} 

e quindi utilizzarlo come questo

MyCrazyInt crazyInt1 = new MyCrazyInt(5); 
MyCrazyInt crazyInt2 = new MyCrazyInt(3); 
MyCrazyInt crazyInt3 = crazyInt1 - crazyInt2; //this will return 8 
crazyInt3 = crazyInt1 + crazyInt2; //this will return 2