把对象当作数组一样使用索引
与程序语言的许多功能一样,索引的优点归结为让你的程序更为直观。索引器使得类的客户能够类似数组一样索引对象实例。
定义索引器
索引器通常也称为灵巧的数组。定义索引器与定义属性是相似的。然而存在两个地方的不同。第一,索引器需要一个索引参数。第二,因为类自身当作一个数组使用,所以this关键字表示索引器的名称。简单的索引器示例:
2 class MyClass
3 {
4 public object this [int idx]
5 {
6 get
7 {
8 // Return desired data.
9 }
10 set
11 {
12 // Set desired data.
13 }
14 }
15 }
16
索引器范例
2using System.Collections;
3
4class MyListBox
5{
6 protected ArrayList data = new ArrayList();
7
8 public object this[int idx]
9 {
10 get
11 {
12 if (idx > -1 && idx < data.Count)
13 {
14 return (data[idx]);
15 }
16 else
17 {
18 throw new InvalidOperationException("[MyListBox.set_Item]" +
19 " Index out of range");
20 }
21 }
22 set
23 {
24 if (idx > -1 && idx < data.Count)
25 {
26 data[idx] = value;
27 }
28 else if (idx == data.Count)
29 {
30 data.Add(value);
31 }
32 else
33 {
34 throw new InvalidOperationException(
35 "[MyListBox.get_Item] Index out of range");
36 }
37 }
38 }
39}
40
41class IndexersApp
42{
43 public static void Main()
44 {
45 MyListBox lbx = new MyListBox();
46 lbx[0] = "foo";
47 lbx[1] = "bar";
48 lbx[2] = "baz";
49 Console.WriteLine("{0} {1} {2}",
50 lbx[0], lbx[1], lbx[2]);
51 }
52}
53
注意这个范例,我检验了数据索引溢出的错误。这不能依赖索引器,因为这如我所提到的:索引器只是方便类的用户能把对象当作一个数组来使用,并且不提供数据的内部表示方式相关的操作。然而,当学习一种新的语言特性时,查看它的实际用途比只看它的语法更有效。因此,在索引器的get/set方法中,我对被传递和存储在类成员ArrayList中的数据进行验证。当被传递的数据无法验证时,在这种情况下我多半选择抛出异常。
深入索引器
当C#编译器发现一个索引器语法时,将自动定义一个命名为Item的属性及相关的get/set方法。
正如你所看到的,在ILDASM树视图最后的条目是Item。如果你双击这个条目,你将看到标准的.property指示符和get_Item和set_Item。如果你尝试在类内部定义get_Item或set_Item方法编译器将出错,因为这些名字与索引器的方法名冲突。在Main方法的MSIL中可以进一步确认:用户访问类的索引器是通过调用get_Item和set_item方法来实现的。
同样注意到set_Item方法把Object引用作为第二个参数。这种安排明显地允许为你选择的任何类型指定索引器-这也是单一基类层次的另外一个优点。
因为对于客户来说,索引器可以把类当作数组看待,因此可以使用foreach迭代索引器,如下代码所示:
2lbx[1] = "bar";
3lbx[2] = "baz";
4
5foreach (object obj in lbx)
6{
7
8}
9
允许你完全把类当作数组看待,不是索引器的原意。无论如何,接口IEmumenterable和类IEnumerate的组合使类的用户能够枚举所定义的集合。
设计指导方针
与其他语言的任何功能一样,索引器有它的局限性(place)。索引器只用在像数组一样直观处理的情景中。当考虑怎样实现一些新的功能影响你的类的用户和思考指导方针,使用更多的具体术语将使你的类更容易使用。
本文资料来源于:《Inside C# Second Edition》中的“Treating Objects Like Arrays by Using Indexers”