2012-01-27 22 views

Trả lời

17

Tôi không hiểu tại sao bạn cần. Nếu bạn muốn tạo một hash-code dựa trên mặc định GetHashCode cho 3 mặt hàng khác nhau, sau đó chỉ cần sử dụng:

Tuple.Create(lastName, firstName, gender).GetHashCode() 

Điều đó sẽ đun sôi xuống tương đương với:

int h1 = lastName.GetHashCode(); 
int h2 = firstName.GetHashCode(); 
int h3 = gender.GetHashCode(); 
return (((h1 << 5) + h1)^(((h2 << 5) + h2)^h3)); 

Đó là khá hợp lý cho một sự kết hợp đa năng như vậy.

Tương tự như vậy:

Tuple.Create(lastName, firstName, gender).Equals(Tuple.Create(lastName2, firstName2, gender2)) 

sẽ đun sôi xuống tương đương với cách gọi:

return ((lastName == null && lastName2 == null) || (lastName != null && lastName.Equals(lastName2))) 
    && ((firstName == null && firstName2 == null) || (firstName != null && firstName.Equals(lastName2))) 
    && ((gender == null && gender2 == null) || (gender != null && gender.Equals(lastName2))); 

Một lần nữa, khoảng tốt như bạn có thể mong đợi.

+1

+1: tuples và các loại vô danh là tuyệt vời để thực hiện GetHashCode(), Equals(), và ToString() – millimoose

+1

Ý tưởng hay sử dụng các lớp 'Tuple' làm lối tắt. Nhưng lưu ý rằng 'Tuple.Create (...). Equals (Tuple.Create (...))' không tương đương với phương thức 'equals' của Guava - đó chỉ là' object.Equals (x, y) '. – LukeH

+1

@ LukeH, cũng vì chúng tôi đã có điều đó, và chúng tôi có điều này quá, có nghĩa là chúng tôi có thể làm tốt hơn so với Guava :) –

1

AFAIK không. Tuy nhiên, viết của riêng bạn không nên quá phức tạp (nb sử dụng biến thể của băm Bernstein):

public static class Objects 
{ 
    public static bool Equals<T>(T item1, T item2, Func<T, IEnumerable<object>> selector) 
    { 
    if (object.ReferenceEquals(item1, item2) return true; 
    if (item1 == null || item2 == null) return false; 

    using (var iterator1 = selector(item1).GetEnumerator()) 
    using (var iterator2 = selector(item2).GetEnumerator()) 
    { 
     var moved1 = iterator1.MoveNext(); 
     var moved2 = iterator2.MoveNext(); 
     if (moved1 != moved2) return false; 
     if (moved1 && moved2) 
     { 
     if (!Equals(iterator1.Current, iterator2.Current)) return false; 
     } 
    } 
    return true; 
    } 

    public static bool Equals(object item1, object item2) 
    { 
    return object.Equals(item1, item2); 
    } 

    public static int GetHashCode(params object[] objects) 
    { 
    unchecked 
    { 
     int hash = 17; 
     foreach (var item in objects) 
     { 
     hash = hash * 31 + item.GetHashCode(); 
     } 
     return hash; 
    } 
    } 
} 
+0

Phương thức 'Equals' của bạn chính xác giống như phương thức tĩnh' object.Equals (x, y) ': http://msdn.microsoft.com/en-us/library/w4hkze5k.aspx – LukeH

+0

@ LukeH Cảm ơn - tại sao tái tạo lại bánh xe ?! Đã cập nhật câu trả lời. –

+0

'Bằng' không hữu ích hơn so với việc triển khai chuẩn được kế thừa. Nó phải có khả năng nêu rõ các lĩnh vực cần được xem xét cho sự bình đẳng. – deamon

Các vấn đề liên quan