日期:2014-05-20  浏览次数:20833 次

重写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