Più robusto Uguale implementazione per classi personalizzate per l'uguaglianza valore in C #

StackOverflow https://stackoverflow.com/questions/570560

  •  05-09-2019
  •  | 
  •  

Domanda

Di 'Ho una classe Point2, e voglio realizzare il seguente Equals:

public override bool Equals ( object obj )

public bool Equals ( Point2 obj )

Questo è dal Effective C # 3 book:

public override bool Equals ( object obj )
{
    // STEP 1: Check for null
    if ( obj == null )
    {
        return false;
    }

    // STEP 3: equivalent data types
    if ( this.GetType ( ) != obj.GetType ( ) )
    {
        return false;
    }
    return Equals ( ( Point2 ) obj );
}

public bool Equals ( Point2 obj )
{
    // STEP 1: Check for null if nullable (e.g., a reference type)
    if ( obj == null )
    {
        return false;
    }
    // STEP 2: Check for ReferenceEquals if this is a reference type
    if ( ReferenceEquals ( this, obj ) )
    {
        return true;
    }
    // STEP 4: Possibly check for equivalent hash codes
    if ( this.GetHashCode ( ) != obj.GetHashCode ( ) )
    {
        return false;
    }
    // STEP 5: Check base.Equals if base overrides Equals()
    System.Diagnostics.Debug.Assert (
        base.GetType ( ) != typeof ( object ) );

    if ( !base.Equals ( obj ) )
    {
        return false;
    }

    // STEP 6: Compare identifying fields for equality.
    return ( ( this.X.Equals ( obj.X ) ) && ( this.Y.Equals ( obj.Y ) ) );
}

E 'questo un peso inutile?

È stato utile?

Soluzione

uguaglianza di sostegno con una gerarchia di ereditarietà è difficile. Hai bisogno di capire esattamente quello che vuoi dire. Avete davvero bisogno di successione qui? In caso contrario - se Point2 deriva direttamente da System.Object, e si può fare sigillato, la vita diventa un po 'più facile. In tal caso vorrei usare:

public override bool Equals (object obj)
{
    return Equals(obj as Point2);
}

public bool Equals (Point2 obj)
{
    // STEP 1: Check for null if nullable (e.g., a reference type)
    // Note use of ReferenceEquals in case you overload ==.
    if (object.ReferenceEquals(obj, null))
    {
        return false;
    }

    // STEP 2: Check for ReferenceEquals if this is a reference type
    // Skip this or not? With only two fields to check, it's probably
    // not worth it. If the later checks are costly, it could be.
    if (object.ReferenceEquals( this, obj))
    {
        return true;
    }

    // STEP 4: Possibly check for equivalent hash codes
    // Skipped in this case: would be *less* efficient

    // STEP 5: Check base.Equals if base overrides Equals()
    // Skipped in this case

    // STEP 6: Compare identifying fields for equality.
    // In this case I'm using == instead of Equals for brevity
    // - assuming X and Y are of a type which overloads ==.
    return this.X == obj.X && this.Y == obj.Y;
}

Altri suggerimenti

Non proprio - si sta contabili per praticamente ogni possibilità. Se questo codice è per qualcosa di diverso da una domanda di zero si dovrebbe considerare i vantaggi di questo approccio perché errori logici a causa di un comportamento strano uguaglianza oggetto sono dolorosi per eseguire il debug.

Mi sembra esattamente quello che ci vuole. Questo intero blocco si riduce a:

"se è esattamente lo stesso esempio, restituisce vero. Se sono istanze separate con lo stesso valori X e Y, ritorno vero. Tutti gli altri casi (nulli, diverso tipo, diversi x / valori y) restituiscono false."

La sua sicuramente più codice di mi piacerebbe voglia di scrivere per un metodo uguale. Ci sono un sacco di controlli ridondanti come il controllo per ReferenceEquals e codici hash (So che questi controlli sono ridondanti perché le ultime righe del controllo funzionale per l'uguaglianza strutturale). Concentrarsi sul codice che è semplice e leggibile.

public bool Equals(object o)
{
    Point2 p = o as Point2;
    if (o != null)
        return this.X == o.X && this.Y == o.Y;
    else
        return false;
}

Dal momento che il metodo equals usa uguaglianza strutturale, assicuratevi di ignorare GetHashCode con un'implementazione in base ai vostri campi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top