您的位置:首页 > 移动开发 > Objective-C

给你的类重写Equals--检测Class是否相等

2006-01-05 08:45 453 查看
在C#的容器中,常用的三个容器数组,ArrayList,Hashtable..数组比较简单,实现某种单一数据的存储,但是并不能自由插入,移除和容纳不同的对象..,所以ArrayList是数组的替代品,并且由于ArrayList可以自由的添加,删除,插入,读取,给我们提供了足够大的自由性,颇得我的青睐..不过使用中,难免有些缺点,感觉最麻烦的就是检测某对象是否在Items中..因为每一个new出来的Class在内存中的表现不相同,即便是同一个类,你new出来两个,然后再判断,也是会一样的!!所以每次使用ArrayList.Contains()检测对象的时候,难免都得不到自己想要的结果..因为每个Class都是继承自Object类..而ArrayList.Contains()的实现是IList.Contains,而此方法是调用Class中的Equals方法判断是否相等,这个时候,可以在自己的对象中覆写Object.Equals方法,以达到自己的目的..注意,如果你覆写了Equals方法,则也要覆写GetHashCode(),因为Equals是用获取Object.GetHashCode()来做判断的.看看下面的代码就明白:
 1

using System;
 2


 3

namespace HashCode_Test
 4





{
 5



/**//// <summary>
 6

///        给你的类加入Equals,测试类
 7

/// </summary>
 8

public class Class2
 9





{
10

    int myHashCode = 0;
11

    public Class2( int id )    //传递进一个int,作为GetHashCode的值
12



    

{
13

    
4000
    myHashCode = id;
14

    }
15

        
16

    //覆写GetHashCode,关键的一步
17

    public override int GetHashCode()    
18



    

{
19

        return myHashCode;
20

    }
21

        
22

    //这步,可有可无,主要是做测试结果用的
23

    public override string ToString()    
24



    

{
25

        return DateTime.Now.ToString();
26

    }
27

        
28



    /**//// <summary>
29

    ///        重载了Equals方法,这步和GetHashCode配合起来才会有效果
30

    /// </summary>
31

    /// <param name="o">要检测的对象</param>
32

    /// <returns>返回是否相同</returns>
33

    public override bool Equals( object o )    
34



    

{
35

        return o.GetHashCode() == myHashCode;
36

    }
37


38

    //在这里使用运算符重载,主要是为了进一步演示Equals
39

    public static bool operator ==(object c1, Class2 c2) 
40



    

{
41

        return c1.GetHashCode().Equals( c2.GetHashCode() );
42

    }
43

    
44

    //当你重载了==运算符后,必须要重载!=运算符
45

    public static bool operator !=(object c1, Class2 c2) 
46



    

{
47

        return c1.GetHashCode().Equals( c2.GetHashCode() );
48

    }
49

        
50

}
51

}
这里是测试代码:

 1

System.Collections.ArrayList arr = new System.Collections.ArrayList();
 2


 3

int i = 0;
 4



for ( i = 0; i < 4 ; i ++ ) 

{
 5

    Class2 class2 = new Class2(i);        //我们添加四个对象
 6

    arr.Add( class2 );
 7

}
 8


 9

for ( i = 0; i < 4 ; i ++ ) 
10





{
11

    Class2 class2 = new Class2(i);        //重新创建四个对象,判断是否和容器中的对象相等
12

    Console.WriteLine( i + ":" + arr.Contains(class2));//全部输出true
13

}
14


15


16


17

Class2 class2_1 = new Class2(1);    //再创建对象1,并添加到容器中,以判断是否有多个对象1存在
18

arr.Add( class2_1  );                
19


20



for ( i = 0;i<arr.Count;i++  ) 

{
21

    Class2 class2_3 = new Class2(1);//这个时候我们要检测出容器中有多少个对象1
22



    if ( arr[i].Equals( class2_3 ) ) 

{//我们用Equals来检测是否相等
23

        Console.WriteLine( "我用Equals找到/t"  );
24

    }
25

    if ( arr[i] == class2_3  )            //我们用==来检测相等
26



    

{
27

        Console.WriteLine( "我用==找到/t"  );
28

    }
29

    Console.WriteLine( arr[i].ToString() + "/t HashCode:" + arr[i] .GetHashCode());            //这里输出HashCode和ToString()查看
30

    
31

}
32


相信上面的代码很容易看的懂..在我的Class2类中覆写了GetHashCode() ,ToString() ,Equals(object o),并重载了==运算符和!=运算符..将传递的id作为HashCode,然后判断当前传递的对象Object.GetHashCode是否等于当前对象的GetHashCode..这样就解决了ArrayList.Contains不能对Class做出正确判断的问题..

另外,还有一个容器Hashtable的使用和判断,并不能用上面的方法解决..因为Hashtable.Contains的实现方法是IDictionary.Contains来做判断..需要实现IDictionary接口的方法才可以.因为牵涉到的内容比较多.所以不能在这里全部写完..关于具体的方法和实现,我会找时间写出来的..

最后大家可以自己做一个没有实现Equals方法的类,再用ArrayList.Contains来做判断..可以看到结果都是flase..和上面的代码是个对比..
这个方法不仅可以用在ArrayList,而且也可以在多个地方使用,比如两个Class之间的关联?Class1和Class2是否关联?? 1

using System;
 2


 3

namespace HashCode_Test
 4





{
 5



/**//// <summary>
 6

///        给你的类加入Equals,测试类
 7

/// </summary>
 8

public class Class2
 9





{
10

    int myHashCode = 0;
11

    public Class2( int id )    //传递进一个int,作为GetHashCode的值
12



    

{
13

        myHashCode = id;
14

    }
15

        
16

    //覆写GetHashCode,关键的一步
17

    public override int GetHashCode()    
18



    

{
19

        return myHashCode;
20

    }
21

        
22

    //这步,可有可无,主要是做测试结果用的
23

    public override string ToString()    
24



    

{
25

        return DateTime.Now.ToString();
26

    }
27

        
28



    /**//// <summary>
29

    ///        重载了Equals方法,这步和GetHashCode配合起来才会有效果
30

    /// </summary>
31

    /// <param name="o">要检测的对象</param>
32

    /// <returns>返回是否相同</returns>
33

    public override bool Equals( object o )    
34



    

{
35

        return o.GetHashCode() == myHashCode;
36

    }
37


38

    //在这里使用运算符重载,主要是为了进一步演示Equals
39

    public static bool operator ==(object c1, Class2 c2) 
40



    

{
41

        return c1.GetHashCode().Equals( c2.GetHashCode() );
42

    }
43

    
44

    //当你重载了==运算符后,必须要重载!=运算符
45

    public static bool operator !=(object c1, Class2 c2) 
46



    

{
47

        return c1.GetHashCode().Equals( c2.GetHashCode() );
48

    }
49

        
50

}
51

}
这里是测试代码:

 1

System.Collections.ArrayList arr = new System.Collections.ArrayList();
 2


 3

int i = 0;
 4



for ( i = 0; i < 4 ; i ++ ) 

{
 5

    Class2 class2 = new Class2(i);        //我们添加四个对象
 6

    arr.Add( class2 );
 7

}
 8


 9

for ( i = 0; i < 4 ; i ++ ) 
10





{
11

    Class2 class2 = new Class2(i);        //重新创建四个对象,判断是否和容器中的对象相等
12

    Console.WriteLine( i + ":" + arr.Contains(class2));//全部输出true
13

}
14


15


16


17

Class2 class2_1 = new Class2(1);    //再创建对象1,并添加到容器中,以判断是否有多个对象1存在
18

arr.Add( class2_1  );                
19


20



for ( i = 0;i<arr.Count;i++  ) 

{
21

    Class2 class2_3 = new Class2(1);//这个时候我们要检测出容器中有多少个对象1
22



    if ( arr[i].Equals( class2_3 ) ) 

{//我们用Equals来检测是否相等
23

        Console.WriteLine( "我用Equals找到/t"  );
24

    }
25

    if ( arr[i] == class2_3  )            //我们用==来检测相等
26



    

{
27

        Console.WriteLine( "我用==找到/t"  );
28

    }
29

    Console.WriteLine( arr[i].ToString() + "/t HashCode:" + arr[i] .GetHashCode());            //这里输出HashCode和ToString()查看
30

    
31

}
32


相信上面的代码很容易看的懂..在我的Class2类中覆写了GetHashCode() ,ToString() ,Equals(object o),并重载了==运算符和!=运算符..将传递的id作为HashCode,然后判断当前传递的对象Object.GetHashCode是否等于当前对象的GetHashCode..这样就解决了ArrayList.Contains不能对Class做出正确判断的问题..

另外,还有一个容器Hashtable的使用和判断,并不能用上面的方法解决..因为Hashtable.Contains的实现方法是IDictionary.Contains来做判断..需要实现IDictionary接口的方法才可以.因为牵涉到的内容比较多.所以不能在这里全部写完..关于具体的方法和实现,我会找时间写出来的..

最后大家可以自己做一个没有实现Equals方法的类,再用ArrayList.Contains来做判断..可以看到结果都是flase..和上面的代码是个对比..
这个方法不仅可以用在ArrayList,而且也可以在多个地方使用,比如两个Class之间的关联?Class1和Class2是否关联??
 1

using System;
 2


 3

namespace HashCode_Test
 4





{
 5



/**//// <summary>
 6

///        给你的类加入Equals,测试类
 7

/// </summary>
 8

public class Class2
 9





{
10

    int myHashCode = 0;
11

    public Class2( int id )    //传递进一个int,作为GetHashCode的值
12



    

{
13

        myHashCode = id;
14

    }
15

        
16

    //覆写GetHashCode,关键的一步
17

    public override int GetHashCode()    
18



    

{
19

        return myHashCode;
20

    }
21

        
22

    //这步,可有可无,主要是做测试结果用的
23

    public override string ToString()    
24



    

{
25

        return DateTime.Now.ToString();
26

    }
27

        
28



    /**//// <summary>
29

    ///        重载了Equals方法,这步和GetHashCode配合起来才会有效果
30

    /// </summary>
31

    /// <param name="o">要检测的对象</param>
32

    /// <returns>返回是否相同</returns>
33

    public override bool Equals( object o )    
34



    

{
35

        return o.GetHashCode() == myHashCode;
36

    }
37


38

    //在这里使用运算符重载,主要是为了进一步演示Equals
39

    public static bool operator ==(object c1, Class2 c2) 
40



    

{
41

        return c1.GetHashCode().Equals( c2.GetHashCode() );
42

    }
43

    
44

    //当你重载了==运算符后,必须要重载!=运算符
45

    public static bool operator !=(object c1, Class2 c2) 
46



    

{
47

        return c1.GetHashCode().Equals( c2.GetHashCode() );
48

    }
49

        
50

}
51

}
这里是测试代码:

 1

System.Collections.ArrayList arr = new System.Collections.ArrayList();
 2


 3

int i = 0;
 4



for ( i = 0; i < 4 ; i ++ ) 

{
 5

    Class2 class2 = new Class2(i);        //我们添加四个对象
 6

    arr.Add( class2 );
 7

}
 8


 9

for ( i = 0; i < 4 ; i ++ ) 
10





{
11

    Class2 class2 = new Class2(i);        //重新创建四个对象,判断是否和容器中的对象相等
12

    Console.WriteLine( i + ":" + arr.Contains(class2));//全部输出true
13

}
14


15


16


17

Class2 class2_1 = new Class2(1);    //再创建对象1,并添加到容器中,以判断是否有多个对象1存在
18

arr.Add( class2_1  );                
19


20



for ( i = 0;i<arr.Count;i++  ) 

{
21

    Class2 class2_3 = new Class2(1);//这个时候我们要检测出容器中有多少个对象1
22



    if ( arr[i].Equals( class2_3 ) ) 

{//我们用Equals来检测是否相等
23

        Console.WriteLine( "我用Equals找到/t"  );
24

    }
25

    if ( arr[i] == class2_3  )            //我们用==来检测相等
26



    

{
27

        Console.WriteLine( "我用==找到/t"  );
28

    }
29

    Console.WriteLine( arr[i].ToString() + "/t HashCode:" + arr[i] .GetHashCode());            //这里输出HashCode和ToString()查看
30

    
31

}
32


相信上面的代码很容易看的懂..在我的Class2类中覆写了GetHashCode() ,ToString() ,Equals(object o),并重载了==运算符和!=运算符..将传递的id作为HashCode,然后判断当前传递的对象Object.GetHashCode是否等于当前对象的GetHashCode..这样就解决了ArrayList.Contains不能对Class做出正确判断的问题..

另外,还有一个容器Hashtable的使用和判断,并不能用上面的方法解决..因为Hashtable.Contains的实现方法是IDictionary.Contains来做判断..需要实现IDictionary接口的方法才可以.因为牵涉到的内容比较多.所以不能在这里全部写完..关于具体的方法和实现,我会找时间写出来的..

最后大家可以自己做一个没有实现Equals方法的类,再用ArrayList.Contains来做判断..可以看到结果都是flase..和上面的代码是个对比..
这个方法不仅可以用在ArrayList,而且也可以在多个地方使用,比如两个Class之间的关联?Class1和Class2是否关联??
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息