简体   繁体   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 
        }
        */ 
    }
}

I was following the guidelines by MSDN . 我遵循MSDN的指导方针。 Two questions: 两个问题:

  1. Have I correctly implemented the equals method? 我是否正确实现了equals方法?
  2. Could someone show me how to implement GetHashCode Correctly for my class? 有人能告诉我如何正确地为我的班级实现GetHashCode吗? MSDN does x ^ y, but I can't do it for mine. MSDN做x ^ y,但我不能为我做。

Well, to not run into any problems, GetHashCode should use all the members that Equals uses and vice versa. 好吧,为了不遇到任何问题, GetHashCode应该使用Equals使用的所有成员,反之亦然。

So in your case: 所以在你的情况下:

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

Best keep in mind what the purpose of these two methods is: With equals YOU define under which circumstances two instances of your class should be treated as, well, equal. 最好记住这两种方法的目的是什么:使用equals你定义在哪种情况下你的类的两个实例应该被视为,相等。 So if in your case this is given iff first name, last name and phone number are equal then this is correct. 因此,如果在您的情况下给出iff名字,姓氏和电话号码相等,那么这是正确的。 The hash method in turn is used to sort or distribute you instances eg in a hash map. 反过来,哈希方法用于对实例进行排序或分发,例如在哈希映射中。 It should be fast and good enough to avoid unwanted clustering. 它应该快速且足够好以避免不必要的群集。 Therefore you often see values multiplied by a prime in hash functions. 因此,您经常会看到值乘以散列函数中的素数。 You have to guarantee that equal objects have the same hash code but not vice versa. 您必须保证相等的对象具有相同的哈希码,但反之则不然。 So different objects may have the same hash code. 因此,不同的对象可能具有相同的哈希码。

A more common method than a simple xor of hash codes, as posted in Filip's answer, is to use a more complicated formula to combine them. Filip的答案中提到的一种比简单的哈希码xor更常用的方法是使用更复杂的公式来组合它们。 Multiply the individual fields' hash codes by different numbers, for example like so: 将各个字段的哈希码乘以不同的数字,例如:

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

(Note the unchecked keyword: integer overflow is expected here, and silent wraparound is exactly the intended behaviour.) (注意unchecked关键字:此处需要整数溢出,而无声环绕正是预期的行为。)

It probably won't make a difference for the concrete types you're dealing with, but in general, it's better. 它可能不会对你正在处理的具体类型产生影响,但总的来说,它会更好。 Consider a simple type containing only two integer values. 考虑一个只包含两个整数值的简单类型。 Consider also that int 's GetHashCode() implementation simply returns its own value. 还要考虑intGetHashCode()实现只返回自己的值。 If you use a simple xor to combine the values, you will have a lot of hash collisions for normal code: the simplest example is that each pair of two identical values will produce the same hash code of zero. 如果使用简单的xor来组合这些值,那么普通代码会产生大量的哈希冲突:最简单的例子是每对两个相同的值将产生相同的零哈希码。

The calculation here is actually the calculation that's done by Tuple<T1, T2, T3> . 这里的计算实际上是由Tuple<T1, T2, T3>完成的计算。 I didn't write it the way Microsoft did, but the actual calculations and numbers should be the same. 我没有像微软那样写它,但实际的计算和数字应该是一样的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C#Equals和GetHashCode - C# Equals and GetHashCode C# 覆盖 GetHashCode 方法 - C# Overriding the GetHashCode method 在C#中创建GetHashCode方法 - Creating the GetHashCode method in C# 为什么 C# 7 ValueTuples 实现 Equals 方法而不实现双等号运算符? - Why do C# 7 ValueTuples implement the Equals method but not the double equals operator? 所有c#类应该实现Equals和GetHashCode吗? - should all c# classes implement Equals and GetHashCode? 我如何实现C#方法的父级 - how do i implement a parent for c# method 覆盖C#中的Object.Equals()实例方法;现在代码分析/ FxCop警告CA2218:“还应该重新定义GetHashCode”。我该抑制吗? - Overriding Object.Equals() instance method in C#; now Code Analysis/FxCop warning CA2218: “should also redefine GetHashCode”. Should I suppress this? 当类实现Equals和GetHashCode时,如何将对象引用用作C#字典中的键? - How do you use an object reference as a key in a C# dictionary when the class implements Equals and GetHashCode? 我是否正确实现了Equals()/ GetHashCode()? - Have I implemented Equals()/GetHashCode() correctly? 新的ReSharper Equals()和GetHashCode()代码生成方法 - New ReSharper Equals() and GetHashCode() code generation method
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM