2009-01-22 51 views
1

任何人都可以告訴我如何ObjectIDGenerator更好(更糟?),然後使用HashSet遍歷對象的層次結構(這可能是recurvise/circular),而不是想要遍歷同一個對象兩次?ObjectIDGenerator與HashSet <T>

回答

4

基本的區別在於每個人如何平等。

ObjectIdGenerator查看參照標識。當檢查一個對象是否已經存在時,它只會對兩個對象實例執行==調用。這將歸結爲參考比較,因爲對象在這一點上是靜態類型的對象。這很好,除非你的對象明確地使用.Equals()來實現相等。如果兩個對象通過.Equals()但是不同的引用相等,ObjectIDGenerator會將它們視爲不同的對象。可能不是你想要的。

另一方面,HashSet允許您自定義通過IEqualityComparer <T>參數比較對象的方式。如果沒有指定,它將使用EqualityComparer <T>。將使用值相等的默認值。此方法將調用.Equals()並依賴它來確定兩個對象是否相等。在你沒有爲你的類型定義一個.Equals()方法的情況下,它會默認回到引用相等,這幾乎肯定是你想要的。

總之,去與HashSet的:)

示例代碼顯示的區別:

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 
} 
相關問題