• 索引器


    开场白:CLR提供了两种属性:无参属性和含参属性,在C#中,前者通常被称为属性(property),后者被称为索引器(indexer)


     索引器的定义-》

     定义索引器的方式与定义属性有些类似,其一般形式如下:
    [修饰符] 数据类型 this[索引类型 index]
    { 
      get{//获得属性的代码}
      
    set{ //设置属性的代码}
    }

      修饰符包括 public,protected,private,internal,new,virtual,sealed,override, abstract,extern.

      数据类型是表示将要存取的数组或集合元素的类型。

     索引器类型表示该索引器使用哪一类型的索引来存取数组或集合元素,可以是整数,可以是字符串;this表示操作本对象的数组或集合成员,可以简单把它理解成索引器的名字,因此索引器不能具有用户定义的名称。
    
     索引器参数可以不止一个,类型也不限于int,几乎可以是任意类型

    索引器内部结构-》

      如果索引器包含get访问器,则会生成"get_Item” 的方法;

      如果索引器包含set访问器,则会生成"set_Item”的方法;

      如果为一个类型设计的索引器要是有其他语言的代码访问,就可能需要更改索引器的默认Item名称了。

    C#允许向索引器应用System.Runtime.ComplierServices.IndexerNameAttribute定制attribute来重命名这些方法

    [IndexerName("Nums")]
     public int this[int post]
    {
                get {}
                set {}
    }

    编译器就会生成名为get_Nums,set_Nums的方法,而不是默认的了。

    缺点:使用IndexerName 如果一个类型中包含多个名称不同的有参属性,C#无法编译代码,因为它的语法不是通过名称来引用索引器。

       C#将索引器是对[]操作符的一种重载方式,但是[]操作符不能用来消除具有不同方法名和相同参数集的有参属性的歧义.

    索引器是属性的一种,它本质上和属性一样是方法。

    索引器可以重载,因此一个类中可以有多个索引器。


    索引器与属性的比较

    索引器与属性都是类的成员,语法上非常相似。索引器一般用在自定义的集合类中,通过使用索引器来操作集合对象就如同使用数组一样简单;而属性可用于任何自定义类,它增强了类的字段成员的灵活性。

                                  属        性                                      索  引  器

     允许调用方法,如同公共数据成员

    允许调用对象上的方法,如同对象是一个数组

     可通过简单的名称进行访问

     可通过索引器进行访问

     可以为静态成员或实例成员

     必须为实例成员

     其get访问器没有参数

     其get访问器具有与索引器相同的形参表

     其set访问器包含隐式value参数

     除了value参数外,其set访问器还具有与索引器相同的形参表


    为什么要用索引器?开发中哪些地方有用到?

    C#中的类成员可以是任意类型,包括数组和集合。当一个类包含了数组和集合成员时,索引器将大大简化对数组或集合成员的存取操作

     数组就是用索引方式

    int[] values={2,4,5,6};

    int i=values[1];

      

      自定义索引器

     class Person
        {
            private string firstName = "一";
            private string secondName = "二";
            public string this[int index, string name]
            {
                get { return index + name; }
            }
            public string this[int index]
            {
                set
                {
                    if (index == 0)
                    {
                        firstName = value;
                    }
                    else if (index == 1)
                    {
                        secondName = value;
                    }
                    else
                    {
                        throw new Exception("not exist!");
                    }
                }
                get
                {
                    if (index == 0)
                    {
                        return firstName;
                    }
                    else if (index == 1)
                    {
                        return secondName;
                    }
                    else
                    {
                        throw new Exception("not exist!");
                    }
                }
            }
        }

      

      string类的索引器是一个只读索引器

    string str = "Jerry";
    Console.WriteLine(str[2]);

      

       一维序列索引器

    string[] theValues = new string[100];
    public string this[int index]
    {
      get
      {
        if (index > 99)
          return default(string);
            return theValues[index];
      }
      set { theValues[index] = value; }
    }

      

      字典索引器

    Dictionary<T, T> dic = new Dictionary<T, T>();
    public T this[T key]
    {
        get
        {
            if (!dic.ContainsKey(key))
               return default(T);
            return dic[key];
         }
        set { dic[key] = value; }
    }

     

      System.Drawing.Imaging.ColorMatrix类中,提供了一个有多个参数的一个索引器的例子

    public float this[int row, int column]
    {
        get
        {
            return this.GetMatrix()[row][column];
        }
        set
        {
            float[][] numArray;
            numArray = this.GetMatrix();
            numArray[row][column] = value;
            this.SetMatrix(numArray);
            return;
        }
    }

      

      System.Collections.Generic.Dictionary类就提供一个索引器,它获取一个值,并返回与该键关联的值。

    public TValue this[TKey key]
    {
        get
        {
            int num;
            TValue local;
            num = this.FindEntry(key);
            if (num < 0)
            {
                goto Label_001E;
            }
            return &(this.entries[num]).value;
        Label_001E:
            ThrowHelper.ThrowKeyNotFoundException();
            return default(TValue);
        }
        set
        {
            this.Insert(key, value, 0);
            return;
        }
    }

  • 相关阅读:
    《PostgreSQL 指南:内幕探索》之基础备份与时间点恢复(下)
    数据和云,半年文章精选(文末赠书)
    js for 循环跳过undefined值
    js for循环,会遇到undefined
    洛谷P3018 [USACO11MAR]树装饰Tree Decoration
    洛谷P3018 [USACO11MAR]树装饰Tree Decoration
    洛谷P3018 [USACO11MAR]树装饰Tree Decoration
    洛谷P3018 [USACO11MAR]树装饰Tree Decoration
    js特效:鼠标滑过图片时切换为动图
    js特效:鼠标滑过图片时切换为动图
  • 原文地址:https://www.cnblogs.com/shenqiboy/p/3132733.html
Copyright © 2020-2023  润新知