与程序语言的许多功能一样,索引的优点归结为让你的程序更为直观。索引器使得类的客户能够类似数组一样索引对象实例。
定义索引器
索引器通常也称为灵巧的数组。定义索引器与定义属性是相似的。然而存在两个地方的不同。第一,索引器需要一个索引参数。第二,因为类自身当作一个数组使用,所以this关键字表示索引器的名称。简单的索引器示例:
![None.gif](/Images/OutliningIndicators/None.gif)
2
![None.gif](/Images/OutliningIndicators/None.gif)
3
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
4
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
5
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
6
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
7
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
8
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
9
![ExpandedSubBlockEnd.gif](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
10
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
11
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
12
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
13
![ExpandedSubBlockEnd.gif](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
14
![ExpandedSubBlockEnd.gif](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
15
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
16
![None.gif](/Images/OutliningIndicators/None.gif)
索引器范例
![None.gif](/Images/OutliningIndicators/None.gif)
2
![None.gif](/Images/OutliningIndicators/None.gif)
3
![None.gif](/Images/OutliningIndicators/None.gif)
4
![None.gif](/Images/OutliningIndicators/None.gif)
5
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
6
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
7
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
8
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
9
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
10
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
11
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
12
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
13
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
14
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
15
![ExpandedSubBlockEnd.gif](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
16
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
17
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
18
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
19
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
20
![ExpandedSubBlockEnd.gif](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
21
![ExpandedSubBlockEnd.gif](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
22
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
23
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
24
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
25
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
26
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
27
![ExpandedSubBlockEnd.gif](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
28
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
29
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
30
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
31
![ExpandedSubBlockEnd.gif](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
32
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
33
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
34
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
35
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
36
![ExpandedSubBlockEnd.gif](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
37
![ExpandedSubBlockEnd.gif](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
38
![ExpandedSubBlockEnd.gif](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
39
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
40
![None.gif](/Images/OutliningIndicators/None.gif)
41
![None.gif](/Images/OutliningIndicators/None.gif)
42
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
43
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
44
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
45
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
46
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
47
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
48
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
49
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
50
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
51
![ExpandedSubBlockEnd.gif](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
52
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
53
![None.gif](/Images/OutliningIndicators/None.gif)
注意这个范例,我检验了数据索引溢出的错误。这不能依赖索引器,因为这如我所提到的:索引器只是方便类的用户能把对象当作一个数组来使用,并且不提供数据的内部表示方式相关的操作。然而,当学习一种新的语言特性时,查看它的实际用途比只看它的语法更有效。因此,在索引器的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迭代索引器,如下代码所示:
![None.gif](/Images/OutliningIndicators/None.gif)
2
![None.gif](/Images/OutliningIndicators/None.gif)
3
![None.gif](/Images/OutliningIndicators/None.gif)
4
![None.gif](/Images/OutliningIndicators/None.gif)
5
![None.gif](/Images/OutliningIndicators/None.gif)
6
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
7
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
8
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
9
![None.gif](/Images/OutliningIndicators/None.gif)
允许你完全把类当作数组看待,不是索引器的原意。无论如何,接口IEmumenterable和类IEnumerate的组合使类的用户能够枚举所定义的集合。
设计指导方针
与其他语言的任何功能一样,索引器有它的局限性(place)。索引器只用在像数组一样直观处理的情景中。当考虑怎样实现一些新的功能影响你的类的用户和思考指导方针,使用更多的具体术语将使你的类更容易使用。
本文资料来源于:《Inside C# Second Edition》中的“Treating Objects Like Arrays by Using Indexers”