关于CollectionBase

今天看了一下C#中接口的东西,发现对CollectionBase(为强类型集合提供抽象基类)中的具体实现原理不是很了解。经过查看一些资料,分析过后得到以下的初步认识。

system.Collections.CollectionBase类主要显示的实现ICollection和IList接口和IEnumerable接口。但只提供了一些要求的执行代码,特别是IList的Clear()和RemoveAt()方法,以及ICollection 的 Count属性,如果要使用提供的功能,就需要自己执行其他代码。具体的显示接口实现,可以查看MSDN的相关资料。(注:ICollection主要是实现将自己的项目复制到一个项目中,IList接口主要用于按照索引单独访问的一组对象)。由于IList接口成员很多,在这里就用Add接口成员来描述,并给出一个《C#入门经典》的例子的阐述。为了便于完成任务,CollectionBase提供了两个受保护的属性(List 和 InnerList),它们可以访问存储的对象本身。(下面的例子就用到了List)

我们的目的是实现一个强类型集合,并且实现基本的添加,删除,和索引访问。这些实现都是通过继承CollectionBase类和使用IList接口来实现的。首先看CollectionBase的几个主要成员:

List成员定义: protected IList List {get;} //一个List属性
显示接口实现: int IList.Add( object  value) //一个显示实现
我们通过List属性调用显示接口来实现元素的添加。同样删除和索引访问都要使用List属性成员来调用显示接口。

CollectionBase实际上就是MS提供给我们的一个简化实现了IList接口的抽象基类。利用它可以使我们更加方便的自定义强类型的集合类
通过使用Reflector可以发现,CollectionBase这个抽象基类,实际上继承了IList,ICollection和IEnumerable三个接口,并且显式地实现了IList接口的Add()和Remove()等方法,另外提供了一个受保护的属性IList List以方便我们使用。

 

public abstract class CollectionBase : IList, ICollection, IEnumerable
{
    // Methods
    int IList.Add(object value);
    void IList.Remove(object value);

    // Properties
    protected IList List get; }
}

 

 

 

下面是代码和阐述:

 

//======================Animals.cs ============================
//强类型化定制集合类
//===========================================================
using System;
using System.Collections;
namespace Ch11Ex02
{
 /// <summary>
 
/// Animals 的摘要说明。
 
/// </summary>

 public class Animals:CollectionBase
 {
  public Animals()
  {
  }


  public void Add(Animal newAnimal)
  {
   List.Add(newAnimal);//List是IList接口的一个引用变量,调用CollectionBase中的显示接口成员int IList.Add(),实现元素的添加。注:  因为int IList.Add()是显示接口成员,所以必须使用IList类型引用变量才能调用
 }


  public void Remove(Animal oldAnimal)
  {
   List.Remove(oldAnimal);//和Add一样,使用List引用变量调用void IList.Remove(object value)
  }


  public Animal this[int animalIndex]  //类中的索引
  {
   get
   {
    return (Animal)List[animalIndex]; //返回对应索引值的Animal对象
   }

   set
   {
    List[animalIndex]=value;
   }

  }

 }

}

//======================Animal.cs ============================
//Animal类,其对象作为Animals集合类的项目
//===========================================================
using System;

namespace Ch11Ex02
{
 /// <summary>
 
/// Animal 的摘要说明。
 
/// </summary>

 public abstract class Animal
 {
  protected string name;
  public Animal()
  {
     name="The animal with no name";
  }


  public Animal(string newName)
  {
   name=newName;
  }


  public string Name
  {
   get
   {
    return name;
   }

   set
   {
    name=value;
   }

  }


  public void Feed()
  {
   Console.WriteLine("{0} has been fed",name);
  }


 }


 public class Cow:Animal
 {
  public void Milk()
  {
   Console.WriteLine("{0} has been milked",name);
  }

  public Cow(string newName):base(newName)
  {
  }

 }


 public class Chicken:Animal
 {
  public void LayEgg()
  {
   Console.WriteLine("{0} has laid an egg",name);
  }


  public Chicken(string newName):base(newName)
  {
  }

 }

}

 

//======================Class1.cs ============================
//主类,一个应用程序
//===========================================================
using System;

namespace Ch11Ex02
{
 /// <summary>
 
/// Class1 的摘要说明。
 
/// </summary>

 class Class1
 {
  /// <summary>
  
/// 应用程序的主入口点。
  
/// </summary>

  [STAThread]
  static void Main(string[] args)
  {
   //
   
// TODO: 在此处添加代码以启动应用程序
   
//
   Animals animalCollection=new Animals();
   animalCollection.Add(new Cow("Jack"));
   animalCollection.Add(new Chicken("Vera"));
   foreach(Animal myAnimal in animalCollection)
   {
    myAnimal.Feed();
   }

  }

 }

}

 

 

 在实际的使用中,为什么我们经常使用List 或者ArrayList 集合类,而很少从CollectionBase中派生集合类呢?我一直不明白,在读《C#入门经典》第三版中,“泛型”一章中有段话是这样描述这个问题的:

为什么不使用CollectionBase中派生类?
      实际上,很多情况下,我们都不会从CollectionBase中派生类。知道内部的工作原理是好事,因为List<T>以相同的方式工作,但CollectionBase是向后兼容的。使用CollectionBase的唯一场合是要更多的控制向类的的用户展示的成员。如果希望集合类的Add()方法使用内部访问修饰符,则使用CollectionBase是最佳选择。

posted @ 2012-05-30 00:10  suncms  阅读(253)  评论(0编辑  收藏  举报