把对象当作数组一样使用索引

        与程序语言的许多功能一样,索引的优点归结为让你的程序更为直观。索引器使得类的客户能够类似数组一样索引对象实例。

定义索引器
       索引器通常也称为灵巧的数组。定义索引器与定义属性是相似的。然而存在两个地方的不同。第一,索引器需要一个索引参数。第二,因为类自身当作一个数组使用,所以this关键字表示索引器的名称。简单的索引器示例:

 1 None.gif
 2 None.gif   class  MyClass
 3 ExpandedBlockStart.gifContractedBlock.gif   dot.gif {
 4InBlock.gif      public object this [int idx]
 5ExpandedSubBlockStart.gifContractedSubBlock.gif      dot.gif{
 6InBlock.gif         get
 7ExpandedSubBlockStart.gifContractedSubBlock.gif         dot.gif{
 8InBlock.gif            // Return desired data.
 9ExpandedSubBlockEnd.gif         }

10InBlock.gif         set 
11ExpandedSubBlockStart.gifContractedSubBlock.gif         dot.gif{
12InBlock.gif            // Set desired data.
13ExpandedSubBlockEnd.gif         }

14ExpandedSubBlockEnd.gif     }

15ExpandedBlockEnd.gif  }

16 None.gif

索引器范例

 1 None.gif using  System;
 2 None.gif using  System.Collections;
 3 None.gif
 4 None.gif class  MyListBox
 5 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 6InBlock.gif    protected ArrayList data = new ArrayList();
 7InBlock.gif
 8InBlock.gif    public object this[int idx]
 9ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
10InBlock.gif        get
11ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
12InBlock.gif            if (idx > -1 && idx < data.Count)
13ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
14InBlock.gif                return (data[idx]);
15ExpandedSubBlockEnd.gif            }

16InBlock.gif            else
17ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
18InBlock.gif                throw new InvalidOperationException("[MyListBox.set_Item]" +
19InBlock.gif                    " Index out of range");
20ExpandedSubBlockEnd.gif            }

21ExpandedSubBlockEnd.gif        }

22InBlock.gif        set
23ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
24InBlock.gif            if (idx > -1 && idx < data.Count)
25ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
26InBlock.gif                data[idx] = value;
27ExpandedSubBlockEnd.gif            }

28InBlock.gif            else if (idx == data.Count)
29ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
30InBlock.gif                data.Add(value);
31ExpandedSubBlockEnd.gif            }

32InBlock.gif            else
33ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
34InBlock.gif                throw new InvalidOperationException(
35InBlock.gif                    "[MyListBox.get_Item] Index out of range");
36ExpandedSubBlockEnd.gif            }

37ExpandedSubBlockEnd.gif        }

38ExpandedSubBlockEnd.gif    }

39ExpandedBlockEnd.gif}

40 None.gif
41 None.gif class  IndexersApp
42 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
43InBlock.gif    public static void Main()
44ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
45InBlock.gif        MyListBox lbx = new MyListBox();
46InBlock.gif        lbx[0= "foo";
47InBlock.gif        lbx[1= "bar";
48InBlock.gif        lbx[2= "baz";
49InBlock.gif        Console.WriteLine("{0} {1} {2}"
50InBlock.gif            lbx[0], lbx[1], lbx[2]);
51ExpandedSubBlockEnd.gif    }

52ExpandedBlockEnd.gif}

53 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迭代索引器,如下代码所示:

1 None.gif lbx[ 0 =   " foo " ;
2 None.giflbx[ 1 =   " bar " ;
3 None.giflbx[ 2 =   " baz " ;
4 None.gif
5 None.gif foreach  ( object  obj  in  lbx)
6 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
7InBlock.gif   dot.gif
8ExpandedBlockEnd.gif}

9 None.gif

      允许你完全把类当作数组看待,不是索引器的原意。无论如何,接口IEmumenterable和类IEnumerate的组合使类的用户能够枚举所定义的集合。

设计指导方针
        与其他语言的任何功能一样,索引器有它的局限性(place)。索引器只用在像数组一样直观处理的情景中。当考虑怎样实现一些新的功能影响你的类的用户和思考指导方针,使用更多的具体术语将使你的类更容易使用。
  

本文资料来源于:《Inside C#  Second Edition》中的“Treating Objects Like Arrays by Using Indexers”

转载于:https://www.cnblogs.com/stzyw/archive/2005/09/23/242819.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值