索引符

  索引符(indexer)是一种特殊类型的属性,可以把它添加到一个类中,以提供类似于数组的访问。实际上,可以通过索引符提供更复杂的访问,因为我们可以用方括号语法定义和使用复杂的参数类型。它最常见的一个用法是对项实现简单的数字索引。

  在 Animal 对象的 Animals 集合中添加一个索引符,如下所示:

  1. public class Animals : CollectionBase
  2. {
  3. ...
  4. public Animal this[int animalIndex]
  5. {
  6. get {
  7. return (Animal)List[animalIndex];
  8. }
  9. set {
  10. List[animalIndex] = value;
  11. }
  12. }
  13. }

  this 关键字需要与方括号中的参数一起使用,除此以外,索引符与其他属性十分类似。这个语法是合理的,因为在访问索引符时,将使用对象名,后跟放在方括号中的索引参数(例如 MyAnimals[0])。

  这段代码对 List 属性使用一个索引符(即在 IList 接口上,可以访问 CollectionBase 中的 ArrayListArrayList 存储了项):

  1. return (Animal)List[animalIndex];

  这里需要进行显式数据类型转换,因为 IList.List 属性返回一个 System.Object 对象。注意,我们为这个索引符定义了一个类型。使用该索引符访问某项时,就可以得到这个类型。这种强类型化功能意味着,可以编写下述代码:

  1. animalCollection[0].Feed();

  而不是:

  1. ((Animal)animalCollection[0]).Feed();

  这是强类型化的定制集合的另一个方便特性。下面扩展上一个示例,实践一下该特性。

  试一试:实现 Animals 集合: Ch11Ex02  (1)在 C:\BegVCSharp\Chapter11 目录中创建一个新控制台应用程序 Ch11Ex02。  (2)在 解决方案资源管理器 窗口中右击项目名,选择 Add | Existing Item 选项。  (3)从 C:\BegVCSharp\Chapter11\Ch11Ex01\Ch11Ex01 目录中选择 Animals.csCow.csChicken.cs 文件,单击 Add 按钮。  (4)修改这 3 个文件中的名称空间声明,如下所示:
  1. namespace Ch11Ex02
  (5)添加一个新类 Animals。  (6)修改 Animals.cs 中的代码,如下所示:
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace Ch11Ex02
  8. {
  9. public class Animals : CollectionBase
  10. {
  11. public void Add(Animal newAnimal)
  12. {
  13. List.Add(newAnimal);
  14. }
  15. public void Remove(Animal newAnimal)
  16. {
  17. List.Remove(newAnimal);
  18. }
  19. public Animal this[int animalIndex]
  20. {
  21. get {
  22. return (Animal)List[animalIndex];
  23. }
  24. set {
  25. List[animalIndex] = value;
  26. }
  27. }
  28. }
  29. }
  (7)修改 Program.cs,如下所示:
  1. static void Main(string[] args)
  2. {
  3. Animals animalCollection = new Animals();
  4. animalCollection.Add(new Cow("Jack"));
  5. animalCollection.Add(new Chicken("Vera"));
  6. foreach (Animal myAnimal in animalCollection)
  7. {
  8. myAnimal.Feed();
  9. }
  10. Console.ReadKey();
  11. }
  示例的说明

  这个示例使用上一节详细介绍的代码,实现类 Animals 中强类型化的 Animal 对象结合。Main() 中的代码仅实例化了一个 Animals 对象 animalCollection,添加了两个项(它们分别时 CowChicken 的实例),再使用 foreach 循环调用这两个对象继承于基类 AnimalFeed() 方法。