C#에서 GetHashCode 및 Equals

6818 단어 HashCode
오늘 C#에서 public override int GetHashCode()와 public override bool Equals(object obj) 다시 쓰기
만약에 우리가 Person 클래스를 가지고 있다면,Hash 기반 Collection(예를 들어HashTable과Dictionary)에 줄 키에게Hash 값을 정의하면 두 개의Person 실례 id가 다르지만 이름은 같다
코드는 다음과 같습니다.


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

namespace TestGetHashCode
{
    class Program
    {
        static void Main(string[] args)
        {

            IDictionary<Person, Object> dic = new Dictionary<Person,Object>();

            Person p1 = new Person();
            p1.Id = 1;
            p1.Name = "name1";
            p1.Age = 20;
            dic.Add(p1, "111");

            Person p2 = new Person();
            p2.Id = 2;
            p2.Name = "name2";
            p2.Age = 20;
            dic.Add(p2, "222");

            if (dic.ContainsKey(p1))
            {
                Console.WriteLine("Contains");
            }
            else
            {
                Console.WriteLine("Not Contains");
            }


          //  IList<Person> list = new List<Person>();


        }

    
    }


    class Person
    {

        private object parent;

        public object Parent
        {
            get { return parent; }
            set { parent = value; }
        }
        private int id;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }
        private string name;
        private int age;

        public int Age
        {
            get { return age; }
            set { age = value; }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public override int GetHashCode()
        {
            Console.WriteLine("In GetHashCode");
            //   Random num = new Random();
            //   int a = num.Next(1,100);
            int hashCode = (this.Id == 0 || this.Id == null) ? 0 : this.Id.GetHashCode();
            if (this.parent != null)
            {
                hashCode = 31 * hashCode + this.parent.GetHashCode();
            }
            return hashCode;
        }


        public override bool Equals(object obj)
        {
            Console.WriteLine("Equal    ");

            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }

            return this.Id == (obj as Person).Id;
        }
 
    } 
}


dic를 실행하고 있습니다.Add(p1, "111"); GetHashCode만 호출됩니다.
dic를 실행하고 있습니다.Add(p2, "222"); GetHashCode만 호출하고 Equals 방법은 호출하지 않습니다.
Personp2의 Id를 P1의 Id와 동일하게 변경하면 ArgumentException {"An item with the same key has already been added."}
이렇게 하면 같은 Id가 있는 Person 실례가 집합에 추가되는 것을 방지할 수 있다
그래서 이렇게 하면 두 실체가 같다는 것을 증명할 수 있다. 그들의 HashCode는 반드시 같지만 HashCode는 반드시 같지 않다. 두 실체는 반드시 같지 않다.
if(dic.ContainsKey(p1)를 실행할 때, 먼저 p1의 GetHashCode 방법을 호출하고 Equals 방법을 조정합니다.
만약 우리가 프로그램을 수정하면, Id는 같을 수 있지만, 이름이 다른 사람도 집합dic에 가입할 수 있다

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

namespace TestGetHashCode
{
    class Program
    {
        static void Main(string[] args)
        {

            IDictionary<Person, Object> dic = new Dictionary<Person,Object>();

            Person p1 = new Person();
            p1.Id = 1;
            p1.Name = "name1";
            p1.Age = 20;
            dic.Add(p1, "111");

            Person p2 = new Person();
            p2.Id = 1;
            p2.Name = "name2";
            p2.Age = 20;
            dic.Add(p2, "222");

            if (dic.ContainsKey(p1))
            {
                Console.WriteLine("Contains");
            }
            else
            {
                Console.WriteLine("Not Contains");
            }


        


        }

    
    }


    class Person
    {

        private object parent;

        public object Parent
        {
            get { return parent; }
            set { parent = value; }
        }
        private int id;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }
        private string name;
        private int age;

        public int Age
        {
            get { return age; }
            set { age = value; }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public override int GetHashCode()
        {
            Console.WriteLine("In GetHashCode");
            //   Random num = new Random();
            //   int a = num.Next(1,100);
            int hashCode = (this.Id == 0 || this.Id == null) ? 0 : this.Id.GetHashCode();
            if (this.parent != null)
            {
                hashCode = 31 * hashCode + this.parent.GetHashCode();
            }
            return hashCode;
        }


        public override bool Equals(object obj)
        {
            Console.WriteLine("Equal    ");

            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }

            return this.Id == (obj as Person).Id && this.Name == (obj as Person).Name;
        }
 
    } 
}


dic를 실행하고 있습니다.Add(p2, "222"); GetHashCode 외에도 Equals 방법을 사용할 수 있습니다
if(dic.ContainsKey(p1)를 실행할 때, 먼저 p1의 GetHashCode 방법을 호출하고 Equals 방법을 조정합니다.이번에는 두 번의 Equals 방법을 사용합니다. 왜냐하면 이때 p1과 p2가 dic 집합 안에 있는HashCode는 모두 같기 때문입니다.처음으로 전송된obj와p2를 비교한 다음에 p1과obj를 비교하여 최종적으로Contains를 출력합니다
Java에서 이 덩어리의 원리는 C#와 같다

좋은 웹페이지 즐겨찾기