簡體   English   中英

c#如何判斷兩個對象是否相等

[英]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 ,如果String1String2是相同的; 它也將炸毀如果String1String2為空。 這是使用 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM