the Indexer(索引器) in C#

所谓索引器(the Indexer)其实就是一种属性(Property)(具体来说是一种含参属性) (详见.NET框架 程序设计 p220)

也可以将它看作是对操作符 [ ] 的重载。


索引器的参数除了可以是Int之外,也可以是double 甚至是object。但只能有一个参数

具体参数类型要求如下:避免为索引器设置除 System.Int32、System.Int64、System.String、System.Object、枚举或泛型类型参数之外的其他参数类型。(摘自MSDN)

另:索引器支持重载。


看看平时最常用的String就大致可以明白索引器的实际作用了。String类型可以通过[n]来访问第n个索引的值(char)。省去了从String -> char[] 的过程。

String str = "Hello World";

//如果不用索引器,我们大概会这么做
char[] charArray = str.ToCharArray();

Console.WriteLine(charArray[1].ToString());//输出e

//有了索引器之后,方便多了,我们可以通过str[i]来直接访问对应的元素
Console.WriteLine(str[1].ToString());//输出e 


索引器的声明模型如下

public T1 this[T2]  //T1为返回值,T2为索引参数的类型

{

  get{...}

  set{...}

}


举个小例子如下:

    public class TestIndexer
    {        
        private DataTable table;
        public TestIndexer()
        {
            //构建一张表
            table = new DataTable();
            table.Columns.Add("key",typeof(Int16));
            table.Columns.Add("value",typeof(String));
            table.Rows.Add("1", "Jan");
            table.Rows.Add("2", "Feb");
            
        }

        public String this[Int16 index]//indexer 1(根据数字月份返回英文)
        {
            get 
            {
                for (int i = 0; i < table.Rows.Count; i++ )
                {
                    if ( (Int16)table.Rows[i]["key"] == index)
                    {
                        return table.Rows[i]["value"].ToString();
                    }
                }
                return "Null";
            }            
        }

   public String this[String season]//indexer 2(根据英文月份返回数字)
        {
            get 
            {
                for (int i = 0; i < table.Rows.Count; i++)
                {
                    if (table.Rows[i]["value"].ToString() == season)
                    {
                        return table.Rows[i]["key"].ToString();
                    }
                }
                return "Null";
            }
        }

        public int this[Int32 i]//indexer 3(干扰器,干扰Indexer1)
        {
            get
            {
                return i;
            }
        }

  }//class

void Main(string[] args)
{
      TestIndexer t = new TestIndexer();
            
    Console.WriteLine("t[1] = {0}", t[(Int16)1]);//调用1号索引器 输出 Jan(将1显式转换为Int16类型)

    Console.WriteLine("t[\"Jan\"] = {0}", t["Jan"]);//调用2号索引器 输出1

    Console.WriteLine("t[1] = {0}", t[1]);//调用3号索引器 输出 1(这个1直接被隐式转换成Int32,因此调用3号索引器)
}
 
  

后记:之前看书时对“索引器可以看做是对 [ ] 操作符的重载”有点不解,但博客写到这里又回头仔细地思考了一下算是明白了。

之前初看索引器的概念时觉得这东西好像很抽象很厉害,现在看来完全是纸老虎。

本质也就是个属性,如果不用索引器也可以改用方法(Method)来完成,例如上例中的几个索引器,可以直接用如下的方法替代:

public String getNameByValue(int i){}//代替索引器1

public String getValueByName(string v){}//代替索引器2

而且在本例中这种对方法的调用比 t [ ] 这种调用方式更具可读性。

 
 

你可能感兴趣的:(.NET,手札)