如何建立自己的Collection? (初級) (.NET) (C#)

 Abstract
在OO設計中,對應於Relational Database的一筆資料,我們會用一個object,如Customer,但多筆資料呢?有些人會用DataSet,有些人會用List<Customer>,這些方法都不錯,但若要設計自己的Collection:Customers type,那該怎麼做呢?

Introduction
使用DataSet(DataTable,DataReader....)或List<Customer>這些代表Collection,理論上並沒有什麼錯,事實上很多人也都這樣用,缺點就是比較沒有OO的flavor。理想上,既然有Customer class代表一筆資料,就應該有Customers class代表多筆資料,而N-Tiers間的傳輸應該是Customers collection,而非DataSet或List<Customer>。

要產生自己的Collection,有兩種方式,一個是.NET 1.0的方式,一個是.NET 2.0的方式。

.NET 1.0方式(在.NET 2.0仍然可以使用)
繼承CollectionBase,CollectionBase是一個abstract class,implement了IList ,ICollection,IEnumerable,已經為Collection做好了基礎架構,我們要做的就是overload this[]、IndexOf()、Add()、Remove()就好,其他的事情,CollectionBase已經幫我們做好了。

 

  1 /**/ /* 
 2(C) OOMusou 2007 
http://oomusou.cnblogs.com
 3
 4Filename    : BuildOwnCollection1.cs
 5Compiler    : Visual Studio 2005 / C# 2.0
 6Description : Demo how to build strong typed collection 
 7Release     : 06/19/2007 1.0
 8
*/

 9
using  System;
10
using  System.Collections;
11
12
public   class  Member  {
13  private string _name;
14  
15  public Member() {}
16  public Member(string name) {
17    _name = name;
18  }

19  
20  public string Name {
21    get return _name;}
22    set { _name = value;}
23  }

24
25  public override bool Equals(object obj) {
26    Member member = (Member)obj;
27    return (_name == member.Name) ? true : false;
28  }

29
30  public override int GetHashCode() {
31    return base.GetHashCode();
32  }

33
34  public static bool operator ==(Member member1, Member member2) {
35    return member1.Equals(member2) ? true : false;
36  }

37
38  public static bool operator !=(Member member1, Member member2) {
39    return !(member1 == member2);
40  }

41}

42
43
public   class  Members : CollectionBase  {
44  public Member this[int index] {
45    get return (Member)List[index]; }
46    set { List[index] = value; }
47  }

48  
49  public int IndexOf(Member member) {
50    return this.List.IndexOf(member);
51  }

52  
53  public void Add(Member member) {
54    this.List.Add(member);
55  }

56
57  public void Remove(Member member) {
58    if (this.IndexOf(member) != -1
59      List.Remove(member);
60  }

61}

62
63
public   class  main  {
64  public static void Main() {
65    Members members = new Members();
66   
67    // insert 
68    members.Add(new Member("Clare"));
69    members.Add(new Member("Jessie"));
70    members.Add(new Member("Jingyi"));
71    
72    // modify
73    int index = members.IndexOf(new Member("Jessie"));
74    if (index != -1) members[index] = new Member("Cerlina");
75
76    // delete
77    members.Remove(new Member("Clare"));
78
79    // search
80    index = members.IndexOf(new Member("Jingyi"));
81    if (index != -1) members.RemoveAt(index);
82    
83    foreach(Member member in members) {
84      Console.WriteLine(member.Name);
85    }

86  }

87}

 

執行結果

 

Cerlina

在Member class中,25行到40行

 

public   override   bool  Equals( object  obj)  {
  Member member 
= (Member)obj;
  
return (_name == member.Name) ? true : false;
}


public   override   int  GetHashCode()  {
  
return base.GetHashCode();
}


public   static   bool   operator   == (Member member1, Member member2)  {
  
return member1.Equals(member2) ? true : false;
}


public   static   bool   operator   != (Member member1, Member member2)  {
  
return !(member1 == member2);
}

整體的目標是為了改寫object的比較方式,在.NET,預設是用reference比較object是否相同,但這對Collection的IndexOf(),Remove()有很大的影響,所以我override了Equals()和GetHashCode(),並對==和!=做了operator overloading。

CollectionBase原本都有實現IndexOf(),Add(),Remove(),但因只針對Object而非Member,所以針對了Member overload了IndexOf(),Add(),Remove(),另外使用了indexer是為了方便Collection的使用。

.NET 2.0 (使用Collection<T>)
繼承Collection<Member>,因為是泛型,所以不用再overload IndexOf(),Add(),Remove(),也不用在定義indexer,因為泛型會直接使用Member,所以code非常精簡。

Collection<T>的架構頗複雜,implement了IEnumerable,IEnumerable<T>,ICollection,ICollection<T>,IList,IList<T>。

 

1 /**/ /* 
 2(C) OOMusou 2007 
http://oomusou.cnblogs.com
 3
 4Filename    : BuildOwnCollection2.cs
 5Compiler    : Visual Studio 2005 / C# 2.0
 6Description : Demo how to build strong typed collection 
 7Release     : 06/19/2007 1.0
 8
*/

 9
using  System;
10
using  System.Collections.ObjectModel;
11
12
public   class  Member  {
13  private string _name;
14
15  public Member() { }
16  public Member(string name) {
17    _name = name;
18  }

19
20  public string Name {
21    get return _name; }
22    set { _name = value; }
23  }

24
25  public override bool Equals(object obj) {
26    Member member = (Member)obj;
27    return (_name == member.Name) ? true : false;
28  }

29
30  public override int GetHashCode() {
31    return base.GetHashCode();
32  }

33
34  public static bool operator ==(Member member1, Member member2) {
35    return member1.Equals(member2) ? true : false;
36  }

37
38  public static bool operator !=(Member member1, Member member2) {
39    return !(member1 == member2);
40  }

41}

42
43
public   class  Members : Collection < Member >   {
44}

45
46
public   class  main  {
47  public static void Main() {
48    Members members = new Members();
49
50    // insert
51    members.Add(new Member("Clare"));
52    members.Add(new Member("Jessie"));
53    members.Add(new Member("Jingyi"));
54
55    // modify
56    int index = members.IndexOf(new Member("Jessie"));
57    if (index != -1) members[index] = new Member("Cerlina");
58
59    // delete
60    members.Remove(new Member("Clare"));
61
62    // search
63    index = members.IndexOf(new Member("Jingyi"));
64    if (index != -1) members.RemoveAt(index);
65
66    foreach (Member member in members) {
67      Console.WriteLine(member.Name);
68    }

69  }

70}

執行結果

Cerlina

 

35行

public   class  Members : Collection < Member >   {
}


非常精簡,只需繼承Collection<Member>即可。

繼承自List<T>也是可以。

不過List<T>的method較多,包含了不少適用於List<T>的算法,如BinarySearch(), Sort(), Reverse(),若用不到,會造成自訂Collection過於臃腫,較占內存。 若會用到這些算法,則應繼承於List<T>。

繼承於Collection<T>是剛剛好Collection會用到的method而已。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值