读书人

重写Equals()带来的困惑解决办法

发布时间: 2012-02-10 21:27:42 作者: rapoo

重写Equals()带来的困惑
最近初学C# 做练习代码如下

C# code
using System;using System.Collections;using System.Collections.Generic;namespace test0829{ class Person    {        public Person()         {        }        public Person(string name)         {            this.Name = name;        }        public string Name{ get; set; }        /// <summary>        /// 重写ToString()方法        /// </summary>        /// <returns></returns>        public override string ToString()        {            return Name.ToString();        }               /// <summary>        /// 重写Equals()方法        /// </summary>        /// <param name="obj"></param>        /// <returns></returns>        public override bool Equals(object obj)        {            if (!(obj is Person))            {                return false;            }            else                return this.Name == ((Person)obj).Name;        }        //public override bool Equals(object obj)        //{        //    return base.Equals(obj);        //}         public override int GetHashCode()        {            return base.GetHashCode();        }            }  class Test    {      Person p1 = new Person("person1");        Person p2 = new Person("person2");        Person p3 = new Person("person1");        Person p4 = new Person("person4");           public void Eqtest()         {                      Console.WriteLine(p1==p3);            Console.WriteLine(p1.Equals(p3));            // base.Equals(p3);            //Equals(p3);            Console.WriteLine(Equals(p1,p3));            //Console.WriteLine(base.ToString());            //Console.WriteLine(Equals(p3));        }            public void Listopt()         {            List<Person> li = new List<Person>();            li.Add(p1);            li.Add(p2);            Console.WriteLine("length= " + li.Count);            foreach(Person p in li)            {                Console.WriteLine(p);            }            //li.RemoveAt(0);            li.Remove(new Person("person1"));            Console.WriteLine("length= "+li.Count);                       foreach (Person p in li)            {                Console.WriteLine(p);            }        }          public void Hashsetopt(Person p)         {            HashSet<Person> ht = new HashSet<Person>();            //ht.Add(p1);            //ht.Add(p2);            //ht.Add(p3);            //ht.Add(p4);            if (!ht.Contains(p))            {                ht.Add(p);            }            foreach(Person pe in ht)            {                Console.WriteLine(pe);            }        }    }class Program    {        static void Main(string[] args)        {            //new Test().hashopt();            new Test().Listopt();            //new Test().Eqtest();            // new Test().Stringpot();            //new Test().Queueopt();            //new Test().Stackopt();            new Test().Hashsetopt(new Person("person1"));            new Test().Hashsetopt(new Person("person1"));            new Test().Hashsetopt(new Person("person2"));                      Console.Read();        }    }    }

如果不重写Equal()时 Li.Remove("Person1")是remove 不掉的 重写之后删掉了 ,为什么在Hashset 中却有2个person1??
remove的时候是比较的Person.Name 为什么contains不是??
运行结果:
length=2
person1
person2
length=1
person2

person1
person1
person2

[解决办法]
没Equal之前,你Li内部的Person 跟你外部new出来的person不是同一个,它们的引用地址不同,默认的equal对于引用类型就是比较两者的引用地址是否相同,而不是去比较它们实际的值是否相同

解释的话就是
List的Remove方法去调用了T对应的Equal方法

第二个我就没看出你的几个person之间有什么关系
都是new Test(),本身就是在构造全新的Test


况且Hashsetopt(Person p) 本身就存在问题,你永远都是在new HashSet

读书人网 >C#

热点推荐