2009-01-22 4 views
1

Quelqu'un peut-il me dire comment ObjectIDGenerator est meilleur (pire?) Puis utiliser HashSet lors de la traversée d'une hiérarchie d'objets (qui peut être recurvise/circulaire), et ne pas vouloir traverser le même objet deux fois?ObjectIDGenerator vs HashSet <T>

Répondre

4

La différence fondamentale réside dans la façon dont chacun fait l'égalité.

ObjectIdGenerator examine l'identité référentielle. Lors de la vérification pour voir si un objet est déjà présent, il suffit de faire un appel == sur les deux instances d'objet. Cela se résume à une comparaison de référence car les objets sont de type statique à être objet à ce stade. C'est correct à moins que votre objet utilise explicitement .Equals() pour l'égalité. Si deux objets sont égaux via .Equals() mais des références différentes, ObjectIDGenerator les considérera comme des objets différents. Probablement pas ce que tu veux. Par contre, HashSet vous permet de personnaliser la façon dont vous comparez les objets via le paramètre IEqualityComparer <T>. Si aucun n'est spécifié, il utilisera EqualityComparer <T> .Default qui utilisera l'égalité des valeurs. Cette méthode appellera .Equals() et en dépendra pour déterminer si deux objets sont égaux. Dans le cas où vous n'avez pas défini une méthode .Equals() pour vos types, elle reviendra par défaut à l'égalité de référence qui est presque certainement ce que vous voulez.

En bref, rendez-vous avec HashSet :)

Exemple de code montrant la différence:

class Person 
{ 
    public readonly string Name; 
    public Person(string name) { Name = name; } 
    public override int GetHashCode() 
    { 
     return Name.GetHashCode(); 
    } 
    public override bool Equals(object obj) 
    { 
     var other = obj as Person; 
     if (other == null) 
     { 
      return false; 
     } 
     return StringComparer.Ordinal.Equals(Name, other.Name); 
    } 
} 

public static void Example() 
{ 
    var gen = new ObjectIDGenerator(); 
    bool isFirst; 
    var person1 = new Person("John"); 
    var person2 = new Person("Bob"); 
    gen.GetId(person1, out isFirst); // isFirst = true 
    gen.GetId(person1, out isFirst); // isFirst = true 
    gen.GetId(person2, out isFirst); // isFirst = false 
    gen.GetId(new Person("John"), out isFirst); // isFirst = true even though they are .Equals() 

    var set = new HashSet<Person>(); 
    set.Add(person1); 
    var contains1 = set.Contains(person1);    // true 
    var contains2 = set.Contains(new Person("John")); // true 
} 
Questions connexes