在三層架構中,實體與實體集合是層間傳遞的核心數據載體。早期開發者常面臨選擇:使用數組、List<T> 等框架集合,還是為每個實體手寫專屬集合類?本文通過對比兩種設計模式,揭示泛型基類如何實現代碼復用與類型安全的雙重提升。
以 Person 實體為例,需手寫 PersonCollection_bad 類,內部封裝 ArrayList,實現 Add、Remove、索引器、IEnumerable 等功能。
public class PersonCollection_bad : IEnumerable {
private ArrayList list = new ArrayList();
public void Add(Person p) { list.Add(p); }
public object this[int index] { get { return list[index]; } ... }
public IEnumerator GetEnumerator() { return list.GetEnumerator(); }
// ... 大量重複代碼
}
缺點明顯:每新增一個實體,就要複製一套幾乎相同的代碼,維護成本極高,且索引器返回 object 需強制轉型,類型不安全。
核心是設計一個實現 IList<T>, IEnumerable<T>, IEnumerator<T> 的泛型基類 BaseCollection<T>,內部用 List<T> 存儲,完整實現增刪改查、索引器、迭代器、複製等標準接口。
public class BaseCollection<T> : IEnumerable<T>, IEnumerator<T>, IList<T> {
private List<T> list = new List<T>();
private int position = -1;
// 完整實現 IList<T> 所有成員:Add, Remove, Insert, IndexOf, this[], CopyTo...
// 實現 IEnumerable<T>/IEnumerator<T>:GetEnumerator, Current, MoveNext, Reset, Dispose
}
具體實體集合只需一行繼承:
public class PersonBaseCollection : BaseCollection<Person> { }
PersonBaseCollection coll = new PersonBaseCollection();
coll.Add(new Person { strID="1", strName="qs1", intAge=21 });
coll.AddRange(new[] { new Person { strID="2", ... }, ... });
coll.Insert(0, new Person { strID="4", ... });
foreach (var p in coll) Console.WriteLine($"{p.strID} {p.strName} {p.intAge}");
文中實現的 IEnumerator<T> 正是迭代器模式的應用。.NET 框架內建集合(List、Dictionary 等)均基於此模式,統一了遍歷介面,支援 foreach、LINQ 等高級特性。理解這一點,有助於在需要自定義遍歷邏輯時(如樹形結構、分頁加載)靈活擴展。