概述:在真正的对象化开发项目中,我们通常会将常用的业务实体抽象为特定的类,如Employee、Customer、Contact等,而多数的类之间会存在着相应的关联或依存关系,如Employee和Customer通过Contact而产生关联、Contact是依赖于Employee和Customer而存在的。在实际的对象应用模块中,可能会有这样的需求:获得一组客户对象(即Customers集合类的实例,如customers),指向其中一个Customer对象(如customers[i]),通过访问这个Customer对象的属性Name(customers[i].Name)和Contacts(如customers[i].Contacts)来查询客户的姓名和与该客户的联络记录,甚至遍历Contacts对象,查找该客户的某次联络摘要(即customers.[i].contacts[x].Summary)。为满足以上集合类的需求,对照.NET Framework 的平台实现,不难发现.NET在Collections命名空间下提供了一系列实现集合功能的类,并且根据适用环境的不同为开发者提供灵活多样的选择性:如通过索引访问使用广泛的ArrayList 和 StringCollection;通常在检索后被释放的先进先出的Queue和后进先出Stack;通过元素键对其元素进行访问Hashtable、SortedList、ListDictionary 和 StringDictionary;通过索引或通过元素键对其元素进行访问的NameObjectCollectionBase 和 NameValueCollection;以及具有集合类的特性而被实现在System.Array下的Array类等。本文将通过实现具有代表性的 “集合类”的两种典型途径,分析对比不同实现方式的差异性与适用环境,让大家了解和掌握相关的一些技术,希望为大家的学习和开发工作起到抛砖引玉的作用(注:作者的调试运行环境为.NET Framework SDK 1.1)。
1.采用从CollectionBase抽象基类继承的方式实现Customers集合类:
首先需要创建为集合提供元素的简单类Customer:
/// <summary>
/// 描述一个客户基本信息的类
/// </summary>
public class Customer
{
/// <summary>
/// 客户姓名
/// </summary>
public string Name;
/// <summary>
/// 描述所有客户联络信息的集合类
/// </summary>
//public Contacts Contacts=new Contacts();
/// <summary>
/// 不带参数的Customer类构造函数
/// </summary>
public Customer()
{
System.Console.WriteLine("Initialize instance without parameter");
}
/// <summary>
/// 带参数的Customer类构造函数
/// </summary>
public Customer(string name)
{
Name=name;
System.Console.WriteLine("Initialize instance with parameter");
}
}
以上就是Customer类的简单框架,实用的Customer类可能拥有更多的字段、属性、方法和事件等。值得注意的是在Customer类中还以公共字段形式实现了对Contacts集合类的内联,最终可形成Customer.Contacts[i]的接口形式,但这并不是最理想的集合类关联方式,暂时将它注释,稍后将详加分析,这个类的代码重在说明一个简单类(相对于集合类的概念范畴)的框架;另外,该类还对类构造函数进行了重载,为声明该类的实例时带name参数或不带参数提供选择性。
接下来看我们的第一种集合类实现,基于从CollectionBase类派生而实现的Customers类:
/// <summary>
/// Customers 是Customer的集合类实现,继承自CollectionBase
/// </summary>
public class Customers: System.Collections.CollectionBase
{
public Customers()
{
}
/// <summary>
/// 自己实现的Add方法
/// </summary>
/// <param name="customer"></param>
public void Add(Customer customer)
{
List.Add(customer);
}
/// <summary>
/// 自己实现的Remove方法
/// </summary>
/// <param name="index"></param>
public void Remove(int index)
{
if (index > Count - 1 || index < 0)
{
System.Console.WriteLine("Index not valid!");
}
else
{
List.RemoveAt(index);
}
}
}
以Customers集合类为例,结合集合辅助技术,希望大家能了解掌握以下知识:
从CollectionBase继承实现集合类
Customers类采用从CollectionBase继承的方式,不再需要在类内声明一个作为Customer集合容器的List对象,因为CollectionBase类已经内置了一个List对象,并已经实现了Count、Clear、RemoveAt等等IList的重要接口(具体请参照MSDN中的CollectionBase 成员),只需要用户显示实现Add、Remove、IndexOf、Insert等等接口,代码中仅简单实现了Add方法和Remove方法的整参数版本作为示例。这种集合类的实现具有简单高效的特点,CollectionBase已经实现了较为完善的功能,实施者只要在其基础上扩展自己所需的功能即可。
索引器的简单实现
我们惯于操作数组的形式通常为array[i],集合类可以看作是“对象的数组”,在C#中,帮助集合类实现数组式索引功能的就是索引器: