Frage

Im Grunde genommen habe ich folgendes so weit:

class Foo {
    public override bool Equals(object obj)
    {
        Foo d = obj as Foo ;
        if (d == null)
            return false;

        return this.Equals(d);
    }

    #region IEquatable<Foo> Members

    public bool Equals(Foo other)
    {
        if (this.Guid != String.Empty && this.Guid == other.Guid)
            return true;
        else if (this.Guid != String.Empty || other.Guid != String.Empty)
            return false;

        if (this.Title == other.Title &&
            this.PublishDate == other.PublishDate &&
            this.Description == other.Description)
            return true;

        return false;
    }
}

So, das Problem ist folgendes: Ich habe einen nicht benötigten Bereich Guid, die eine eindeutige Kennung ist. Wenn diese nicht gesetzt ist, dann muß ich versuchen, Gleichheit, um zu bestimmen, basierend auf ungenauen Messwerten als einen Versuch der Bestimmung, ob zwei Objekte gleich sind. Dies funktioniert gut, aber es GetHashCode() chaotisch ... Wie soll ich vorgehen? Eine naive Implementierung wäre so etwas wie:

public override int GetHashCode() {
    if (this.Guid != String.Empty)
        return this.Guid.GetHashCode();

    int hash = 37;
    hash = hash * 23 + this.Title.GetHashCode();
    hash = hash * 23 + this.PublishDate.GetHashCode();
    hash = hash * 23 + this.Description.GetHashCode();
    return hash;
}

Aber was sind die Chancen der beiden Arten von Hash-Kollision? Sicher, ich würde nicht erwarten, dass es 1 in 2 ** 32 werden. Ist dies eine schlechte Idee, und wenn ja, wie soll ich es tun?

War es hilfreich?

Lösung

Ich glaube nicht, gibt es ein Problem mit dem Ansatz, den Sie verwenden gewählt haben. ‚Zu viel‘ über Hash-Kollisionen besorgniserregend ist fast immer ein Hinweis auf über denken, das Problem; solange der Hash sehr wahrscheinlich ist, anders zu sein, sollten Sie in Ordnung sein.

Am Ende kann man sogar sowieso die Description aus dem Hash Weglassen zu prüfen, ob es sinnvoll ist, die meiste Zeit Objekte zu erwarten, dass auf ihren Titel und Veröffentlichungsdatum unterscheiden basiert (Bücher?).

Sie könnten auch erwägen die GUID in der Hash-Funktion ohne Berücksichtigung zusammen, und es nur in der Equals Implementierung verwenden unwahrscheinlich (?) Fall von Hash-Kollisionen eindeutig zu machen.

Andere Tipps

Eine sehr einfache Hash-Code-Methode für benutzerdefinierte Klassen XOR bitweise jeder der ist hash Felder Codes zusammen. Es kann so einfach wie dies:

int hash = 0;
hash ^= this.Title.GetHashCode();
hash ^= this.PublishDate.GetHashCode();
hash ^= this.Description.GetHashCode();
return hash;

Von der Link oben :

  

XOR hat folgende nette Eigenschaften:

     
      
  • Es hängt nicht von der Reihenfolge der Berechnung.
  •   
  • Es ist nicht „Abfall“ Bits. Wenn Sie auch nur ein Bit in einer der Komponenten ändern, wird der Endwert ändern.
  •   
  • Es ist schnell, ein einzelner Zyklus auf selbst die primitivsten Computer.
  •   
  • Es bewahrt eine gleichmäßige Verteilung. Wenn die beiden Stücke, die Sie kombinieren gleichmäßig verteilt sind, werden so die Kombination sein. Mit anderen Worten, neigen sie nicht den Bereich der Digest in ein engeres Band kollabieren.
  •   

XOR funktioniert nicht gut, wenn Sie erwarten, dass in Ihre Felder doppelte Werte haben als doppelte Werte einander aufheben wird, wenn XOR-verknüpft. Da Sie zusammen drei unabhängige Felder Hashing das kein Problem in diesem Fall sein sollte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top