c#中的equal和getHashCode

C#中的Equals和getHashCode

Equals 的基本用法,我就不说,这里我们来看看getHashCode

hashCode主要用在hashtable类的。是为了快速的验证两个对象是否相等。

如果两个对象的hashcode不等,这两个对象就不等,

如果hashcode相等,再进一步比较equals方法。

有什好处:因为hashcode是int,比较它们是否相等速度非常快,可以提高性能。

理解一:我们先看看,GetHashCode 在对基于hashcode的集合(hashtable 和 dictionary) 基于key、value的集合的影响;

    public class Person
    {
        public int ID { get; set; }

        public string Name { get; set; }

        public override bool Equals(object obj)
        {
            if(obj==null || GetType() != obj.GetType())
            {
                return false;
            }
            return this.ID == (obj as Person).ID;
        }

        public override int GetHashCode()
        {
            int hashCode=(this.ID==0 || this.ID==null)?0:this.ID.GetHashCode();
            return hashCode;
        }
    }

    class Program
    {

        static void Main(string[] args)
        {

            //dictionary 和 hastable 是基于hascdoe的 key的; hashcode 必须是唯一的,不重复的额

            IDictionary<Person, Object> dic = new Dictionary<Person, Object>();
            var p1 = new Person() { ID = 1, Name = "jack" };
            var p2 = new Person() { ID = 2, Name = "tom" };
            var p3 = new Person() { ID = 2, Name = "tom" };
            
            dic.Add(p1, "1");
            dic.Add(p2, "2");
            dic.Add(p3, "3");

            Console.WriteLine(p2.Equals(p3));   //如果仅仅是重写我们的equals的话,我们的p2 和p3 将白视作相等的对象;

            //然后他们的hashcode 却不是相等的;
           //而且我们的额每次运行,都会得到不同的值;
            Console.WriteLine(p2.GetHashCode());
            Console.WriteLine(p3.GetHashCode());
            Console.WriteLine("contains");

            if (dic.ContainsKey(p3))
            {
                //如果仅仅是重写我们的euqals的话,在被添加到我们的基于key的hashtable 中
                //就会出现重复(严格意义上,说是我们的对象值,但引用不同,因为都是通过new 出来的不同对象),违反我hashtable的 不可重复性
                Console.WriteLine("contains");
            }
            else
            {
                //所以要保证hashtable的完整性,我们这里就要重写gethashCode()
                //我们把判断重复的基准定义为我们的额id,当然也可以多个
                Console.WriteLine("no");
                //ps 如果你重写gethashcode,你走不到这一步来就报错:已添加了具有相同键的项。
            }

理解二:

尽量用最快的时间对对象进行初步判断

public class Person
    {
        public int Id { get; set; }

        public Person(int i)
        {
            Id = i;
        }
        public override bool Equals(object obj)
        {
            Console.WriteLine("call Equals");
            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }
            return Id == (obj as Person).Id;
        }

        public override int GetHashCode()
        {
            Console.WriteLine("call GetHashCode");
            return Id % 2;

        }
    }

        class Program
        {
            static void Main(string[] args)
            {
            var p1 = new Person(1);
            var p2 = new Person(2);
            var p3 = new Person(3);

            var dic = new Dictionary<Person, object>();
            dic.Add(p1,1);
            Console.WriteLine("----------------");
            dic.ContainsKey(p1);
            Console.WriteLine("----------------");
            dic.ContainsKey(p2);

            Console.ReadLine();


        }

       }

 执行结果:

 正如我们所料的,先调用getHashCode,如果,hashCode相等,就会接着掉我们的equals 来判断,自定义对象是否相等;

当GetHashCode可以直接分辨出不相等时,Equals就没必要调用了,而当GetHashCode返回相同结果时,Equals方法会 被调用从而确保判断对象是否真的相等。所以,

还是那句话:GetHashCode没必要一定把对象分辨得很清楚(况且它也不可能,一个int不可能代表所 有的可能出现的值),有Equals在后面做保障。GetHashCode仅需要对对象进行快速判断。GetHashCode没必要一定把对象分辨得很清楚

(况且它也不可能,一个int不可能代表所 有的可能出现的值)

实例说话:

.... 未完待续;

这里补充一个好文章:

http://blog.jobbole.com/90593/

关于hascode的建议:

http://book.51cto.com/art/201109/292340.htm

对等比较:

http://www.cnblogs.com/souliid/p/5718968.html

http://blog.csdn.net/lan_liang/article/details/50234439

原文地址:https://www.cnblogs.com/mc67/p/7278101.html