为什么覆写了Equals,还要覆写GetHashCode呢
如果你传递给Hashtable的key是Class,而如何保证key的唯一呢??因为Hashtable还是用到了HashCode做为验证唯一性,所以你还要在你的类覆写GetHashCode(),并且也要重写Equals()以判断是否相等..具体问题可以看给你的类重写Equals--检测Class是否相等 .基础的东西这里都有说明
现在来看Hashtable的具体实现,首先你添加一对键/值后,会将键和对象的引用放入存储桶,Hashtable的键索引是按key对象的GetHashCode方法计算的,查找的时候也是用查找的键与存储的键对比,对比的方法还是要依赖Equals!!这个过程也说明了,为什么覆写了GetHashCode之后也要覆盖Equals了..看代码:
上面的代码实例化了四个类,其中两个小王,两个小李,先添加小李1和小王1到Hashtable中,然后用新的小王2和小李2进行查找Hashtable,因为作为键的User类重写了GetHashCode和Equals,并且实例的时候也都是用的小王和小李,并且他们的string.GetHashCode是一样的..所以会被找到...最后程序又试图添加小李2到Hashtable中,但是因为里面已经存在了一个相同的key.GetHashCode,所以添加导致了异常...上面的输出结果是:
现在来看Hashtable的具体实现,首先你添加一对键/值后,会将键和对象的引用放入存储桶,Hashtable的键索引是按key对象的GetHashCode方法计算的,查找的时候也是用查找的键与存储的键对比,对比的方法还是要依赖Equals!!这个过程也说明了,为什么覆写了GetHashCode之后也要覆盖Equals了..看代码:
1//============= 用户类 ==================
2public class User
3{
4 private string name = null;
5 public User(string name)
6 {
7 this.name = name;
8 }
9
10 public override string ToString() //覆写ToString()
11 {
12 return name;
13 }
14
15 //这里因为name是不重复的,所以获取name的HashCode,作为
16 public override int GetHashCode()
17 {
18 return ToString().GetHashCode();
19 }
20
21 /// <summary>
22 /// 覆写Equals,判断对象是否具有相同的
23 /// </summary>
24 /// <param name="obj"></param>
25 /// <returns></returns>
26 public override bool Equals(object obj)
27 {
28 User u = obj as User;
29 if ( u == null ) //如果不能转换为当前Class,则返回false
30 return false;
31 if ( this.name == u.name && this.ToString() == u.ToString() )
32 return true;
33
34 return false;
35 }
36
37}
38
39// ============ 对应用户的信息 ==============
40public class UserInfo
41{
42 private User u;
43 public UserInfo(User us)
44 {
45 this.u = us;
46 }
47
48 public override string ToString()
49 {
50 return u.ToString() + "的信息";
51 }
52
53}
54
55//========== 测试代码 Main ==================
56static void Main(string[] args)
57{
58 User u1 = new User("小李");
59 User u2 = new User("小王");
60 UserInfo info1 = new UserInfo(u1);
61 UserInfo info2 = new UserInfo(u2);
62 System.Collections.Hashtable hs = new System.Collections.Hashtable();
63
64 hs.Add( u1,info1 );
65 hs.Add( u2,info2 );
66
67 User u3 = new User("小李");
68 UserInfo info3 = new UserInfo(u1);
69 User u4 = new User("小王");
70
71 Console.WriteLine( hs[u3] );
72 Console.WriteLine( hs[u4] );
73 try {
74 hs.Add( u3, info3);
75 }catch(ArgumentException ee) {
76 Console.WriteLine( ee.Message );
77 }
78
79}
2public class User
3{
4 private string name = null;
5 public User(string name)
6 {
7 this.name = name;
8 }
9
10 public override string ToString() //覆写ToString()
11 {
12 return name;
13 }
14
15 //这里因为name是不重复的,所以获取name的HashCode,作为
16 public override int GetHashCode()
17 {
18 return ToString().GetHashCode();
19 }
20
21 /// <summary>
22 /// 覆写Equals,判断对象是否具有相同的
23 /// </summary>
24 /// <param name="obj"></param>
25 /// <returns></returns>
26 public override bool Equals(object obj)
27 {
28 User u = obj as User;
29 if ( u == null ) //如果不能转换为当前Class,则返回false
30 return false;
31 if ( this.name == u.name && this.ToString() == u.ToString() )
32 return true;
33
34 return false;
35 }
36
37}
38
39// ============ 对应用户的信息 ==============
40public class UserInfo
41{
42 private User u;
43 public UserInfo(User us)
44 {
45 this.u = us;
46 }
47
48 public override string ToString()
49 {
50 return u.ToString() + "的信息";
51 }
52
53}
54
55//========== 测试代码 Main ==================
56static void Main(string[] args)
57{
58 User u1 = new User("小李");
59 User u2 = new User("小王");
60 UserInfo info1 = new UserInfo(u1);
61 UserInfo info2 = new UserInfo(u2);
62 System.Collections.Hashtable hs = new System.Collections.Hashtable();
63
64 hs.Add( u1,info1 );
65 hs.Add( u2,info2 );
66
67 User u3 = new User("小李");
68 UserInfo info3 = new UserInfo(u1);
69 User u4 = new User("小王");
70
71 Console.WriteLine( hs[u3] );
72 Console.WriteLine( hs[u4] );
73 try {
74 hs.Add( u3, info3);
75 }catch(ArgumentException ee) {
76 Console.WriteLine( ee.Message );
77 }
78
79}
上面的代码实例化了四个类,其中两个小王,两个小李,先添加小李1和小王1到Hashtable中,然后用新的小王2和小李2进行查找Hashtable,因为作为键的User类重写了GetHashCode和Equals,并且实例的时候也都是用的小王和小李,并且他们的string.GetHashCode是一样的..所以会被找到...最后程序又试图添加小李2到Hashtable中,但是因为里面已经存在了一个相同的key.GetHashCode,所以添加导致了异常...上面的输出结果是:
1小李的信息
2小王的信息
3已添加项。字典中的键: “小李” 所添加的键: “小李”
2小王的信息
3已添加项。字典中的键: “小李” 所添加的键: “小李”