《.NET程序员面试秘笈》----面试题13 举例说明索引器的作用

简介: 【考点】索引器的理解,this在索引器中的作用。

本节书摘来自异步社区《.NET程序员面试秘笈》一书中的第1章,面试题13,作者: 张云翯, 更多章节内容可以访问云栖社区“异步社区”公众号查看。

面试题13 举例说明索引器的作用

.NET程序员面试秘笈
【考点】索引器的理解,this在索引器中的作用。

【出现频率】

【解答】

索引器可以使客户程序很方便地访问类中的集合或数组,访问方法类似于通过索引访问数组,并且索引器向客户程序隐藏了内部的数据结构。索引器和属性同样使用get和set访问器读取、写入值,不过索引器的get和set访问器必须具有与索引器相同的形参表。但是属性可以为静态成员,而索引器必须为实例成员。索引器不支持类似于属性的自动实现的语法。

说明:

形参表即为声明索引器时接收的形式参数。
本例描述了索引器在类中的具体应用,其参数可为整型、字符串等类型,也可为多个(如索引多维数组)。在ch01目录下新建一个程序文件,并命名为Index.cs,编写代码如程序1.14所示。

程序1.14 索引器示例:Index.cs

  using System;
  class Index
  {
    static void Main()
    {
      Console.WriteLine("我的暑假安排:");
      Plan p = new Plan();            //创建Plan类型的实例p
      for (int i = 0; i < p.Length; i++)     //从0到days数组元素个数的循环
      {
        Console.Write("+" + p[i] + "\t+");   //输出days数组的元素值
        Console.Write(p[p[i]] + "\n");     //输出content数组的元素值
      }
    }
  }
  class Plan       //声明Plan类
  {
    //声明2个字符串类型的数组字段
    private string[] days = new string[7] { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };
    private string[] content = new string[7] { "看书", "游泳", "打篮球", "踢足球", "和朋友一起玩游戏", "参加计算机培训班", "做暑假作业"};
    //用this声明属性,并接收1个整数类型的参数,只有get访问器,表明只读
    internal string this[int i]
    {
      get
      {
        return days[i];
      }
    }
    //用this声明属性,并接收1个字符串类型的参数,只有get访问器,表明只读
    internal string this[string s]
    {
      get
      {
        return content[getindex(s)];
      }
    }
    //声明getindex方法,接收1个字符串参数,可返回参数在days数组中的索引值
    private int getindex(string s)
    {
      int j = 0;                 //用于days属性值的索引计数
      foreach (string t in days)       //遍历days数组元素
      {
        if (s == t)             //判断所接收字符串参数是否等于days数组
        {
          return j;  //如果参数等于days数组某个元素值,则返回这个元素的索引值(整型)
        }
        j++;
      }
      return -1;
    }  
    //声明Length属性,用于访问days数组的元素个数
    internal int Length
    {
      get
      {
        return days.Length;
      }
    }
  }

除了在类中应用索引器,在接口中也可以声明索引器,并被其他类实现,在ch01目录下新建一个程序文件,并命名为IndexInterface.cs,编写代码如程序1.15所示。

程序1.15 接口索引器示例:IndexInterface.cs

  using System;
  class IndexInterface
  {
    static void Main()
    {
      Iplan p = new Plan();           //创建Iplan类型的p,引用Plan类的实例
      for (int i = 0; i < p.Length; i++)    //从0到days数组元素个数的循环
      {
        if (i % 3 == 0)              //判断计数器i是否为3的倍数或i是否为0
        {
          Console.Write("\n+" + p[i] + "\t");  //输出days数组的元素值,前面加换行
        }
        else
        {
          Console.Write("+" + p[i] + "\t");    //输出days数组的元素值
        }
      }
    }
  }
  interface Iplan            //声明Iplan接口
  {
    string this[int i]        //声明未实现的索引器,接收1个整型参数
    {
      get;
    }
    int Length            //声明未实现的Length属性
    {
      get;
    }
  }
  class Plan : Iplan          //声明Plan,并实现接口
  {
    //声明2个字符串类型的数组字段
    private string[] days = new string[7] { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };
    //实现接口的索引器
    public string this[int i]
    {
      get
      {
        return days[i];
      }
    }
    //实现接口的属性
    public int Length
    {
      get
      {
        return days.Length;
      }
    }
  }

在命令行下编译Index.cs后,执行Index程序,其效果如图1.20所示。


1c8161bf1b0670ac6e2c29394174252e11a01998

在索引器示例中,声明了一个Plan类(代表计划),存储了一个学生在暑假中每个礼拜周一到周日的活动。类中定义了两个字符串类型的数组字段,days数组用于存储周几,content数组则相应地存储了每天安排的活动内容。类中定义了两个索引器,接收整型参数的索引器可返回days数组相应的元素值,而接收字符串参数的索引器则返回content数组相应的元素。整个程序工作步骤如下所示:

(1)创建Plan类的实例p,通过p实例可以直接使用索引器访问集合。

(2)建立一个for循环,以i变量为计数器,i初始值为0,终止值为p的Length属性减去1。在类中,p的Length属性可返回days数组的元素个数,本例中p的Length属性值为7,则for循环次数为7次。

(3)在循环体中,依次输出两个索引器的返回值。

说明:

本例的重点在于字符串参数在索引器中的使用,通过getindex方法,判断字符串参数是否等于days中的元素,如果相等则返回索引值(整型)。最后通过索引值查询content数组相应索引的元素,这样就将两个数组联系起来了。
在命令行下编译IndexInterface.cs后,执行IndexInterface程序,其效果如图1.21所示。


6d9a42b4f9889e0cbc259554e11ec4b2528efe44

接口的索引器和类中的索引器差别不大,只是类似于接口方法的声明,接口中索引器不能提供实现,必须由实现接口的类实现这个索引器。具体在本例中,声明了Iplan接口,接口中声明了索引器和Lenth属性,并且索引器和属性都是只读的。Plan类实现了这个接口,其索引器返回days数组的元素值,Length属性返回days数组的元素个数。程序工作的步骤如下:

(1)创建Iplan类型的引用变量p,并引用Plan类的实例。

(2)建立1个for循环,以i变量为计数器,i初始值为0,终止值为p的Length属性减去1。本例中p的Length属性值为7,则for循环次数为7次。

(3)在循环体中,首先判断i是否为3的倍数或i是否为0,如果是则换行输出索引器的返回值,否则直接输出索引器的返回值。

【分析】

类似于属性,访问类或结构的集合或数组类型可用索引器实现,索引器用this关键字声明。其声明方法如下代码所示:

数据类型 this[参数列表]
{
 get
 {
  以参数为索引返回集合或数组数据;
 }
 set
 {
  分配值到参数索引的元素;
 }
}

可见,索引器的访问器和属性类似,都是使用get和set,不过索引器的访问器不能添加修饰符。通过get和set访问器的选用,可确定索引器可读写、只读和只写的功能。索引器的参数类型和参数个数是索引器的签名,在同一个类中,多个索引器必须有不同的签名。

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

相关文章
|
3月前
|
存储 关系型数据库 MySQL
阿里面试:为什么要索引?什么是MySQL索引?底层结构是什么?
尼恩是一位资深架构师,他在自己的读者交流群中分享了关于MySQL索引的重要知识点。索引是帮助MySQL高效获取数据的数据结构,主要作用包括显著提升查询速度、降低磁盘I/O次数、优化排序与分组操作以及提升复杂查询的性能。MySQL支持多种索引类型,如主键索引、唯一索引、普通索引、全文索引和空间数据索引。索引的底层数据结构主要是B+树,它能够有效支持范围查询和顺序遍历,同时保持高效的插入、删除和查找性能。尼恩还强调了索引的优缺点,并提供了多个面试题及其解答,帮助读者在面试中脱颖而出。相关资料可在公众号【技术自由圈】获取。
|
2月前
|
SQL 关系型数据库 MySQL
阿里面试:1000万级大表, 如何 加索引?
45岁老架构师尼恩在其读者交流群中分享了如何在生产环境中给大表加索引的方法。文章详细介绍了两种索引构建方式:在线模式(Online DDL)和离线模式(Offline DDL),并深入探讨了 MySQL 5.6.7 之前的“影子策略”和 pt-online-schema-change 方案,以及 MySQL 5.6.7 之后的内部 Online DDL 特性。通过这些方法,可以有效地减少 DDL 操作对业务的影响,确保数据的一致性和完整性。尼恩还提供了大量面试题和解决方案,帮助读者在面试中充分展示技术实力。
|
3月前
|
存储 关系型数据库 MySQL
贝壳面试:什么是回表?什么是索引下推?
在40岁老架构师尼恩的读者交流群中,近期有成员获得了得物、阿里、滴滴等一线互联网企业的面试机会,遇到了诸如“MySQL索引下推”、“回表查询”等重要面试题。由于缺乏准备,部分成员未能通过面试。为此,尼恩系统地整理了相关知识点,帮助大家提升技术实力,顺利通过面试。具体内容包括MySQL的架构、回表查询的工作原理及其性能问题、索引下推的底层原理和优势等。此外,尼恩还提供了优化建议和实战案例,帮助大家更好地理解和应用这些技术。尼恩的技术资料《尼恩Java面试宝典PDF》也收录了这些内容,供后续参考。
贝壳面试:什么是回表?什么是索引下推?
|
7月前
|
算法 Java 调度
《面试专题-----经典高频面试题收集四》解锁 Java 面试的关键:深度解析并发编程进阶篇高频经典面试题(第四篇)
《面试专题-----经典高频面试题收集四》解锁 Java 面试的关键:深度解析并发编程进阶篇高频经典面试题(第四篇)
79 0
|
3月前
|
SQL 关系型数据库 MySQL
美团面试:mysql 索引失效?怎么解决? (重点知识,建议收藏,读10遍+)
本文详细解析了MySQL索引失效的多种场景及解决方法,包括破坏最左匹配原则、索引覆盖原则、前缀匹配原则、`ORDER BY`排序不当、`OR`关键字使用不当、索引列上有计算或函数、使用`NOT IN`和`NOT EXISTS`不当、列的比对等。通过实例演示和`EXPLAIN`命令分析,帮助读者深入理解索引失效的原因,并提供相应的优化建议。文章还推荐了《尼恩Java面试宝典》等资源,助力面试者提升技术水平,顺利通过面试。
|
5月前
|
缓存 NoSQL Redis
一天五道Java面试题----第九天(简述MySQL中索引类型对数据库的性能的影响--------->缓存雪崩、缓存穿透、缓存击穿)
这篇文章是关于Java面试中可能会遇到的五个问题,包括MySQL索引类型及其对数据库性能的影响、Redis的RDB和AOF持久化机制、Redis的过期键删除策略、Redis的单线程模型为何高效,以及缓存雪崩、缓存穿透和缓存击穿的概念及其解决方案。
|
6月前
|
SQL 缓存 关系型数据库
面试题MySQL问题之实现覆盖索引如何解决
面试题MySQL问题之实现覆盖索引如何解决
70 1
|
6月前
|
存储 SQL 索引
面试题MySQL问题之使用SQL语句创建一个索引如何解决
面试题MySQL问题之使用SQL语句创建一个索引如何解决
63 1
|
5月前
|
索引
【面试题】串联所有单词的子串,找到所有符合条件的串联子串的起始索引
【面试题】串联所有单词的子串,找到所有符合条件的串联子串的起始索引
58 0
|
6月前
|
存储 安全 Java
Java面试题:Java内存管理、多线程与并发框架:一道综合性面试题的深度解析,描述Java内存模型,并解释如何在应用中优化内存使用,阐述Java多线程的创建和管理方式,并讨论线程安全问题
Java面试题:Java内存管理、多线程与并发框架:一道综合性面试题的深度解析,描述Java内存模型,并解释如何在应用中优化内存使用,阐述Java多线程的创建和管理方式,并讨论线程安全问题
61 0