簡體   English   中英

C#正確實現Equals方法,如何實現GetHashCode方法

[英]C# Implementing the Equals Method Correctly and How do I implement the GetHashCode Method

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Crystal_Message
{
    class Person
    {
        private string firstName ="";
        private string lastName= "";
        private string phone="";


        public Person(string firstName, string lastName, string phone)
        {
            this.FirstName = firstName;
            this.LastName = lastName;
            this.PhoneNumber = phone;
        }

        public string FirstName
        {
            get { return firstName; }

            private set
            {
                if (string.IsNullOrWhiteSpace(value)){

                    throw new ArgumentNullException("Must Include First Name");
                }

                this.firstName = value;
            }

        }

        public string LastName
        {
            get { return lastName; }

            private set
            {
                if (string.IsNullOrWhiteSpace(value)){

                    throw new ArgumentNullException("Must Include Last Name");
                }

                this.lastName = value;
            }

        }

        public string PhoneNumber
        {
            get { return phone; }

            private set
            {
                if (string.IsNullOrWhiteSpace(value)){

                    throw new ArgumentNullException("Must Include Phone Number");
                }

                this.phone = value;
            }

        }


        public override string ToString()
        {
            return "First Name: " + this.FirstName + " " + " Last Name: " + this.LastName + " " + " Phone Number: " + this.PhoneNumber;
        }

        public override bool Equals(object obj)
        {
            if(obj == null)
            {
                return false;
            }

            Person testEquals = obj as Person;

            if((System.Object)testEquals == null)
            {
                return false;
            }

            return (this.firstName == testEquals.firstName) && (this.lastName == testEquals.lastName) && (this.phone == testEquals.phone);   

        }

        /*
        public override int GetHashCode()
        {
           return 
        }
        */ 
    }
}

我遵循MSDN的指導方針。 兩個問題:

  1. 我是否正確實現了equals方法?
  2. 有人能告訴我如何正確地為我的班級實現GetHashCode嗎? MSDN做x ^ y,但我不能為我做。

好吧,為了不遇到任何問題, GetHashCode應該使用Equals使用的所有成員,反之亦然。

所以在你的情況下:

public override int GetHashCode()
{
    return firstName.GetHashCode() ^ lastName.GetHashCode() ^ phone.GetHashCode();
}

最好記住這兩種方法的目的是什么:使用equals你定義在哪種情況下你的類的兩個實例應該被視為,相等。 因此,如果在您的情況下給出iff名字,姓氏和電話號碼相等,那么這是正確的。 反過來,哈希方法用於對實例進行排序或分發,例如在哈希映射中。 它應該快速且足夠好以避免不必要的群集。 因此,您經常會看到值乘以散列函數中的素數。 您必須保證相等的對象具有相同的哈希碼,但反之則不然。 因此,不同的對象可能具有相同的哈希碼。

Filip的答案中提到的一種比簡單的哈希碼xor更常用的方法是使用更復雜的公式來組合它們。 將各個字段的哈希碼乘以不同的數字,例如:

public override int GetHashCode()
{
    unchecked
    {
        return (firstName.GetHashCode() * 33 ^ lastName.GetHashCode()) * 33 ^ phone.GetHashCode();
    }
}

(注意unchecked關鍵字:此處需要整數溢出,而無聲環繞正是預期的行為。)

它可能不會對你正在處理的具體類型產生影響,但總的來說,它會更好。 考慮一個只包含兩個整數值的簡單類型。 還要考慮intGetHashCode()實現只返回自己的值。 如果使用簡單的xor來組合這些值,那么普通代碼會產生大量的哈希沖突:最簡單的例子是每對兩個相同的值將產生相同的零哈希碼。

這里的計算實際上是由Tuple<T1, T2, T3>完成的計算。 我沒有像微軟那樣寫它,但實際的計算和數字應該是一樣的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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