19.3.2 ReadOnlyCollectionBase

如果需要创建一个只读集合,就只能扩展ReadOnlyCollectionBase基类了。该类也提供了一个名为InnerList的属性,此属性是只读属性。实际上,真正负责存储数据的是基类中私有变量list。InnerList属性返回的是一个ArrayList类型的变量,此属性的get访问器会检查私有变量list是否为null,如果是就先实例化它,再返回实例化后的list变量;否则直接返回list变量,如下所示:


protected ArrayList InnerList

{

get

{

if(this.list==null)

{

this.list=new ArrayList();

}

return this.list;

}

}


注意,此属性的访问级别是protected,只能被ReadOnlyCollectionBase类自己以及它的派生类使用。因为要自定义一个只读的集合类型,因此派生类必须确保基类中的list集合变量中的数据不被修改。

作为示例,我们定义了一个名为Students的只读集合。再次提醒大家,此时定义的是一个只读集合,因此要特别注意如下几个问题:

❑不要提供能改变集合中数据的方法,例如Add、Remove等。

❑不要提供默认构造函数,因为有了默认构造函数就可以直接实例化集合类型,那么集合中数据何时初始化呢?如果放在默认构造函数中,那么得到的将是一个永远都是不变的数据的只读集合,这显然不是我们的初衷所在。

❑要提供一个带参数的构造函数,在集合初始化的同时初始化集合中的数据,因为没有改变集合数据的方法,因此集合在实例化后就再也不允许改变了。

代码清单19-15 演示了如何定义一个自定义集合。

代码清单19-15 使用ReadOnlyCollectionBase自定义集合代码示例


using System;

using System.Collections;

namespace ProgrammingCSharp4

{

class CollectionSample

{

public static void Main()

{

IList stuList=new ArrayList();

stuList.Add(new Student{Name="Tom",Sex="Male"});

stuList.Add(new Student{Name="Alice",Sex="Female"});

stuList.Add(new Student{Name="Jack",Sex="Male"});

Students students=new Students(stuList);

PrintCollectionInfo(students,"students");

}

public class Students:ReadOnlyCollectionBase

{

//带参数的构造函数,在集合初始化的同时初始化数据

public Students(ICollection students)

{

InnerList.AddRange(students);

}

public int IndexOf(Object student)

{

return(InnerList.IndexOf(student));

}

public bool Contains(Object student)

{

return(InnerList.Contains(student));

}

//索引器

public Object this[int index]

{

get

{

return(InnerList[index]);

}

}

}

public class Student

{

public string Name{get;set;}

public string Sex{get;set;}

public string Grade{get;set;}

public DateTime Birthday{get;set;}

}

private static void PrintCollectionInfo(Students stuList,string varName)

{

Console.Write("{0}:",varName);

foreach(Student student in stuList)

{

Console.Write("\t{0}",student.Name);

}

Console.WriteLine();

Console.WriteLine("Count:{0}",stuList.Count);

}

}

}


上述代码的运行结果为:


students:Tom Alice Jack

Count:3

请按任意键继续……