前两天刚刚学习完了属性,这两天又搂完了索引器,发现两者非常的相似,但是相似之外还有一些不同之处。今天就来总结一下索引器--Indexers

索引器的作用及格式

索引器的作用就是能够使类或者结构体的实例对象像数组一样使用下标的方式访问集合对象。索引器的书写格式和属性非常的类似,像是一个带有参数的属性,但是属性名只能使用this关键字,并且指定了索引类型,下面看一个简单的例子:

  class MyClass{
     int[] numInts = new int[10];//定义一个数组
     public int this[int index]{
         get
        {
             return numInts[index];
        }
         set
        {
             numInts[index] = value;
        }
    }
}
 
 class Program
{
static void Main(string[] args)
{
MyClass myClass = new myClass();
myClass[0] = 1;
myClass[1] = 2;
int num = myClass[1];
}
}

在这个例子中,myClass通过get访问器获取numInts中的值,通过set访问器将值传递给value进行赋值,这是最简单的操作。但其实在get和set访问器中还可以进行一些条件的判断,比如在get访问器中判断下标是否越界;在set访问器中判断传值是否超出限定范围等等,能做的操作太多了。

只读&只写索引器的实现

上面说过,索引器与属性非常的相似都具有一对访问器,只是访问器接收的参数有所不同。既然拥有类似的访问器,那么只读或者只写功能的索引器与只读或者只写功能的属性,也是差不多的,下面具体阐述一下。 在之前的属性文章的说到过属性的只读或者只写有两种实现方式:

  1. 隐藏getter或者setter

  2. 给getter或者setter添加private访问修饰符 这里同样适用于索引器,只不过有以下几点需要注意:

  3. 通过隐藏getter来实现只读索引器的方式,只能在类中实现,结构体中的索引器不能隐藏getter

  4. 通过给getter添加private访问修饰符实现只读索引器也只能在类中实现,结构体中getter必须能被外界访问到

  5. 使用添加private访问修饰符的方式来是实现只读或者只写索引器时,getter和setter必须同时存在,缺一不可。 下面使用两种方式分别实现只读索引器:

class MyClass
{
private int[] nums = new []{1, 2, 3, 4, 5, 6, 7};

public int this[int index]//通过添加private实现只写索引器
{
get{
               return this.nums[index];
}
private set { this.nums[index] = value; }
}
} class MyClass
{
private int[] nums = new []{1, 2, 3, 4, 5, 6, 7};

public int this[int index]//通过隐藏setter实现只读索引器
{
get{
               return this.nums[index];
}
}
}

索引器在接口中的使用

接口中能够声明的类型只有四种,其中就包含索引器。在接口中,索引器的使用也和属性大抵相似,getter和setter同样没有方法体,只用";"结尾。也可以通过隐藏getter或者setter来定义只读或者只写索引器,具体在接口中的使用如下:

  interface ITestFace
{
int this[int index] { get; set; }
}

同属性一样,派生类在实现索引器的时候也有两种选择:

  1. 可以为索引器添加virtual关键字,使后续的派生类能够进行重写

class Test2:ITestFace
{
private int[] count = new[] {1, 2, 3, 4};
public virtual int this[int index]
{
get => count[index];
set => count[index] = value;
}
}

class Test1:Test2
{
private int[] count = new[] {0,0,0,0 };
public override int this[int index]
{
get
{
return this.count[index];
}
}
}
class Program
{
static void Main(string[] args)
{
Test2 Test1 = new Test1();
Console.WriteLine(Test1[1]);
}
}
0
请按任意键继续. . .
  1. 直接在索引器前添加接口名称,删除访问修饰符,进行显示接口实现

class Test2:ITestFace
{
private int[] count = new[] {1, 2, 3, 4};
int ITestFace.this[int index]
{
get => count[index];
set => count[index] = value;
}
}
class Program
{
static void Main(string[] args)
{
ITestFace tf = new Test2();
Console.WriteLine(tf[1]);
}
}
2
请按任意键继续. . .

使用显示接口实现的形式,索引器不属于派生类所有,只能被对应接口类型的派生类实例对象所使用。

索引器的其他使用方式

以上用到的索引器都是只包含一个索引值,但其实索引器的所引致可以包含多个,根据自己的需求来使用,这里就不过多介绍了,需要的可以自行Google或者百度。下面介绍一下如何在索引器中使用表达式主体定义。 表达式主体定义和lambda表达式很像,概念什么的这里就略去了,直接进入主题,在C#6当中,如果索引器只读,且get访问器只有一条语句,那么就可以使用表达式主体定义的方式进行书写,更加简洁:

  
 class MyClass2
{
private int[] nums = new []{1, 2, 3, 4, 5, 6, 7};

public int this[int index] => this.nums[index];
}

这种方式只适用于只读索引器,但是在C#7当中,还有另外一种使用表达式主体定义的方式,来简便的书写索引器,如下所示:

  class MyClass3
{
private int[] nums = new []{1, 2, 3, 4, 5, 6, 7};

public int this[int index] {
           get=>this.nums[index];
           set=> nums[index] = value;
}
}

以上,就是关于索引器的一些内容,不足之处还请指教,下面列出一些使用索引器的注意事项,供大家使用时参考:

  1. 通过索引器传递进来的值会传递给value变量,value的类型必须与索引器的类型相同

  2. 索引器不能作为ref或者out参数使用,数组可以

  3. 索引器只属于对象,不能使用static进行修饰

  4. 结构体中也可以使用属性,但是使用时结构体需要使用关键字new进行初始化,因为索引器只属于对象

  5. 索引器和属性很相似,属于有参的属性,使类或者结构体可以访问像数组一下访问数据

  6. 使用索引器获取数据或者修改数据,接收或者传递的值的类型必须与索引器的类型相同

  7. 索引器和属性相同,也可以通过隐藏get或者set访问器来实现只读索引器或者只写索引器,但是在结构体中必须保留get访问器,类中可以选择性的隐藏

  8. 索引器的只读或者只写也可以通过给get或者set访问器添加合适的访问修饰符private来实现,但是在结构体中get访问器不能设为私有的或者被保护的,只能为public类型的

PS:以上均是自己学习之后理解所写,水平有限难免会出现错误之处,总是唯恐给阅读到小伙伴造成误导,所以希望能够以质疑的态度去浏览,也希望小伙伴能够批评指出,共同成长。

C#中的索引器(Indexers)的更多相关文章

  1. C#中的索引器原理

    朋友们,还记得我们在C#语言开发中用到过索引器吗? 记得在获得DataGridView控件的某列值时:dgvlist.SelectedRows[0].Cells[0].Value; 记得在获得List ...

  2. C#中的索引器的简单理解和用法

    索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,使程序看起来更为直观,更容易编写. 1.索引器的定义 C#中的类成员可以是任意类型,包括数组和集合.当一个类包含了数组和集合成员时,索引器 ...

  3. C#中的索引器

    在Java中,一般会这样使用get,set方法: class Person{ private String name; public void setName(String name){ this.n ...

  4. C# 接口中的索引器

    索引器可在 接口(C# 参考) 上声明.接口索引器的访问器与类索引器的访问器具有以下方面的不同: 接口访问器不使用修饰符. 接口访问器没有体. 因此,访问器的用途是指示索引器是读写.只读还是只写.以下 ...

  5. 描述一下C#中索引器的实现过程,是否只能根据数字进行索引?

    不是.可以用任意类型. 索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,使程序看起来更为直观,更容易编写. 1.索引器的定义 C#中的类成员可以是任意类型,包括数组和集合.当一个类包含了 ...

  6. C# 中常用的索引器

    使用 C# 中的索引器和 JavaScript 中访问对象的属性是很相似. 之前了解过索引器,当时还把索引器和属性给记混了, 以为索引器就是属性,下面写下索引器和属性的区别,以及怎么使用索引器 先说明 ...

  7. C# 索引器,实现IEnumerable接口的GetEnumerator()方法

    当自定义类需要实现索引时,可以在类中实现索引器. 用Table作为例子,Table由多个Row组成,Row由多个Cell组成, 我们需要实现自定义的table[0],row[0] 索引器定义格式为 [ ...

  8. 索引器(C# 编程指南)

    原文地址:https://msdn.microsoft.com/zh-cn/library/6x16t2tx(VS.80).aspx 索引器允许类或结构的实例按照与数组相同的方式进行索引.索引器类似于 ...

  9. C# 索引器简介

    索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,是程序看起来更为直观,更容易编写. 1.索引器的定义 C#中的类成员可以是任意类型,包括数组和集合.当一个类包含了数组和集合成员时,索引器 ...

随机推荐

  1. SpringBoot统一异常处理后TX-LCN分布式事务无法捕获异常进行回滚

    通常我们使用SpringBoot都会进行统一异常处理,例如写一个BaseController,在BaseController里进行统一异常处理,然后其他的Controller都继承BaseContro ...

  2. vue 后退不刷新,前进刷新 keep-alive

    最近在开发中遇到了这样的一个问题: A.B.C三个页面,有如下这样的场景: (1)从页面A离开进入B或C的时候,缓存A页面的数据,并且返回到A后,能保持A页面的跳转前职位 (2)离开B进入C的时候,缓 ...

  3. HDU 6068 - Classic Quotation | 2017 Multi-University Training Contest 4

    /* HDU 6068 - Classic Quotation [ KMP,DP ] | 2017 Multi-University Training Contest 4 题意: 给出两个字符串 S[ ...

  4. HDU 6078 - Wavel Sequence | 2017 Multi-University Training Contest 4

    /* HDU 6078 - Wavel Sequence [ DP ] | 2017 Multi-University Training Contest 4 题意: 给定 a[N], b[M] 要求满 ...

  5. 【EXE报错】win10运行C#程序保存报错:HTTP 无法注册URL ,进程不具有此命名空间的访问权限

    在win10系统运行C#程序出现以下报错 异常信息 [1]异常信息:HTTP 无法注册 URL http://+:13000/Core/Real/HandheldService/.进程不具有此命名空间 ...

  6. 小米 oj 找到第N个数字||

    Mycode: #include<iostream> #include<stdio.h> #include<string.h> using namespace st ...

  7. 百度智能api接口汇总

    一:自然语言处理 # -*- coding: utf-8 -*- # @Author : FELIX # @Date : 2018/5/18 9:47 # pip install baidu-aip ...

  8. AGC032F One Third

    很奇怪的一个题.看见了无从下手.概率期望好题. 给一个面积为 \(1\) 的圆,经过圆心随机幅角切直径 \(n\) 次,定义 \(f(x) = \min |S - \frac{1}{3}|\),其中 ...

  9. DataTable转List,DataTable转为Model对象帮助类

    DataTable转List,DataTable转为Model对象帮助类 public class ModelConvertHelper<T> where T : new() { publ ...

  10. Ranorex连接Android

    开始在Android上进行移动测试 只需按照下面的步骤开始使用Android进行移动测试. 1.连接设备(USB/Wi-Fi) 2.在Ranorex中添加设备 3.将设备名称设置为参数值 4.运行示例 ...