一起探索索引器的奥秘吧
 索引器 (indexer)
 C#语言一个最令人感兴趣的地方就是类的索引器(indexer)。简单说来,所谓索引器就是一类特殊的属性,通过它们你就可以像引用数组一样引用自己的类。这就说明这一功能在创建集合类的场合特别有用,而在其他某些情况下,比如处理大型文件或者抽象某些有限资源等,能让类具有类似数组的行为当然也是非常有用的。
索引器允许类或结构的实例按照与数组相同的方式进行索引。索引器类似于属性,不同之处在于它们的访问器采用参数。它可以使得像数组那样对对象使用下标。它提供了通过索引方式方便地访问类的数据信息的方法,那么首先让我们概述下属性这个概念以便了解些必要的背景知识。
属性 (property
   所谓属性方法其实就是特殊的类成员,它实现了对私有类域的受控访问。在C#语言中有两种属性方法,其一是get,通过它可以返回私有域的值,其二是set,通过它就可以设置私有域的值。比如说,以下面的代码为例,其间创建了一个FirstName属性,由它控制对私有类成员firstname的访问:
    class Person
    {
        private string firstname;
        public string FirstName
        {
            get { return firstname; }
            set { firstname = value; }
        }
} 
 
属性声明可以如下编码
       Person p = new Person();
       p.FirstName = "Lamont";
       Console.WriteLine(p.FirstName);
 
这样看来属性声明倒更像是域声明,只不过它还声明了两个特殊的成员,MSDN说法就是所谓的访问函数(accessor)。当某一表达式的右边调用属性或者属性用作其他子程序(或者函数)的参数时即会调用get访问函数。反之,当表达式左边调用属性并且通过隐式传递value参数设置私有域值的情况下就会调用set访问函数。你可以创建只读属性,方法是省略set访问函数,这样任何设置属性的尝试都会产生编译错误。
   要声明类或结构上的索引器,要使用this关键字,例如:
        public int this[int index] //声明索引器
        {
            // get and set 访问
        }
  索引器的修饰符有:newpublicprotectedinternalprivatevirtualsealedoverrideabstractextern。当索引器声明包含extern修饰符时,称该索引器为外部索引器。因为外部索引器声明不提供任何实际的实现,所以它的每个访问器声明都由一个分号组成。
  索引器的签名由其形参的数量和类型组成。它不包括索引器类型或形参名。如果在同一类中声明一个以上的索引器,则它们必须具有不同的签名。
  索引器值不归类为变量;因此,不能将索引器值作为refout参数来传递。
  下面用一个例子来说明如何声明和使用索引器。
  在本示例中,定义了一个泛型类,并为其提供了简单的getset访问器方法(作为分配和检索值的方法)。Program 类为存储字符串创建了此类的一个实例。代码如下:
        class SampleCollection<T>
        {
            private T[] arr = new T[100];
            public T this[int i]
            {
                get { return arr[i]; }
                set { arr[i] = value; }
            }
        }
  下面是如何使用上述代码实现的索引器,具体代码示例如下:
    class Program
    {
        static void Main(string[] args)
        {
 SampleCollection<string> s = new SampleCollection<string>();
             s[0] = "索引器的使用";
            System.Console.WriteLine(s[0]);
        }
}
 
C#并不将索引类型限制为整数。例如,对索引器使用字符串可能是有用的。通过搜索集合内的字符串并返回相应的值,可以实现此类的索引器。如下所示:
 
using System;
using System.Collections;;
  class IndexClass
  {
      private Hashtable ht = new Hashtable();
      public object this[object key]
      {
      get { return ht[key]; }  
      set { ht[key] = value; }
       }
} 
 
下面再谈谈属性与索引器的差别:
   类的每一个属性都必须拥有唯一的名称,而类里定义的每一个索引器都必须拥有唯一的签名(signature)或者参数列表(这样就可以实现索引器重载)。属性可以是static(静态的)而索引器则必须是实例成员。为索引器定义的访问函数可以访问传递给索引器的参数,而属性访问函数则没有参数。
扩展:接口
 类似数组的行为常受到程序实现者的喜爱,所以你还可以为接口定义索引器,IList IDictionary集合接口都声明了索引器以便访问其存储的项目。
在为接口声明索引器的时候,记住声明只是表示索引器的存在。你只需要提供恰当的访问函数即可,不必包括范围修饰符。以下代码把索引器声明为接口IImplementMe的一部分:  
 interface IImplementMe {
                             string this[int index]
                             {
                                 get;
                                 set;
                             }            
                      } 
相应实现的类则必须为IimplementMe的索引器具体定义getset访问函数。
     先写到这里,也只能理解到这一步了,有不足的地方希望能够得到大家的批评指正。