在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
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是否關聯??