[英]c# How to find if two objects are equal
我想知道比較兩個對象並確定它們是否相等的最佳方法。 我覆蓋了 GethashCode 和 Equals。 所以一個基本的類看起來像:
public class Test
{
public int Value { get; set; }
public string String1 { get; set; }
public string String2 { get; set; }
public override int GetHashCode()
{
return Value ^ String1.GetHashCode() ^ String2.GetHashCode();
}
public override bool Equals( object obj )
{
return GetHashCode() == obj.GetHashCode();
}
}
因此,出於測試目的,我創建了兩個對象:
Test t = new Test()
{
Value = 1,
String1 ="One",
String2 = "One"
};
Test t2 = new Test()
{
Value = 1,
String1 = "Two",
String2 = "Two"
};
bool areEqual = t.Equals( t2 );
在測試中,盡管兩個對象不同,但這個 areEqual 返回 true 事件。 我意識到這是因為 String1 和 String2 在每個對象中都是相同的值,因此在散列時會相互抵消。
有沒有更好的方法來散列對象,我擁有的方法可以解決我的問題?
您當前的相等方法已損壞 - 值多於可能的哈希碼。 偶爾會有不相等但給出相同散列的值是完全合理的(並且是預期的)。 等於應該檢查實際值:
public override bool Equals(object obj)
{
Test test = obj as Test;
if (obj == null)
{
return false;
}
return Value == test.Value &&
String1 == test.String1 &&
String2 == test.String2;
}
需要注意的幾點:
您生成的哈希碼將給予任何固定的值相同的方式Value
,如果String1
和String2
是相同的; 它也將炸毀如果String1
或String2
為空。 這是使用 XOR 進行散列的一個不幸方面。 我更喜歡這樣的事情:
// Put this extension method in a utility class somewhere public static int SafeGetHashCode<T>(this T value) where T : class { return value == null ? 0 : value.GetHashCode(); } // and this in your actual class public override int GetHashCode() { int hash = 19; hash = hash * 31 + Value; hash = hash * 31 + String1.SafeGetHashCode(); hash = hash * 31 + String2.SafeGetHashCode(); return hash; }
一般來說,當涉及到繼承時,相等就變得棘手了。 您可能需要考慮密封您的班級。
您可能還想實現IEquatable<Test>
你Equals
是不正確-應該定義意味着什么兩樣東西相等-並具有相同的散列碼不是不意味着平等(但是,不同的散列碼不意味着不相等)。 如果“相等”的意思是“兩個字符串成對相等”,則進行測試。
再一個更好的哈希; xor 因這個而臭名昭著,因為通過 xor 與自身的值獲得 0 是微不足道的。 更好的方法可能是這樣的:
int i = 0x65407627;
i = (i * -1521134295) + Value.GetHashCode();
i = (i * -1521134295) + (String1 == null ? 0 : String1.GetHashCode());
i = (i * -1521134295) + (String2 == null ? 0 : String2.GetHashCode());
return i;
簡單的
Object.Equals(obj1, obj2);
您可以將兩個對象序列化為 JSON,然后比較兩個字符串以查看它們是否相同。
例如
JavaSriptSerializer serialiser = new JavaScriptSerializer();
string t1String = serialiser.Serialize(t);
string t2String = serialiser.Serialize(t2);
if(t1String == t2String)
return true; //they are equal
else
return false;
對於任意兩個對象,對象相等意味着哈希碼相等,但是,哈希碼相等並不意味着對象相等。 來自 MSDN 上的Object.GetHashCode
:
散列函數必須具有以下屬性:
如果兩個對象比較相等,則每個對象的 GetHashCode 方法必須返回相同的值。 但是,如果兩個對象不相等,則兩個對象的 GetHashCode 方法不必返回不同的值。
換句話說,你的Equals
寫錯了。 它應該是這樣的:
public override bool Equals(object obj)
{
Test other = obj as Test;
if (other == null)
return false;
return (Value == other.Value)
&& (String1 == other.String1)
&& (String2 == other.String2);
}
GetHashCode
適用於集合(如Dictionary<K, V>
)以快速確定近似相等。 Equals
用於比較兩個對象是否真的相同。
函數 Equals 不會總是只針對相同類型進行測試,難道不應該是:
//override
public bool Equals(Test other)//(object obj)
{
//return GetHashCode() == obj.GetHashCode();
return (Value == other.Value) &&
(String1 == other.String1) &&
(String2 == other.String2);
}
問候 哎呀
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.