C#中的索引器(Indexers)
前两天刚刚学习完了属性,这两天又搂完了索引器,发现两者非常的相似,但是相似之外还有一些不同之处。今天就来总结一下索引器--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访问器中判断传值是否超出限定范围等等,能做的操作太多了。
只读&只写索引器的实现
上面说过,索引器与属性非常的相似都具有一对访问器,只是访问器接收的参数有所不同。既然拥有类似的访问器,那么只读或者只写功能的索引器与只读或者只写功能的属性,也是差不多的,下面具体阐述一下。 在之前的属性文章的说到过属性的只读或者只写有两种实现方式:
隐藏getter或者setter
给getter或者setter添加private访问修饰符 这里同样适用于索引器,只不过有以下几点需要注意:
通过隐藏getter来实现只读索引器的方式,只能在类中实现,结构体中的索引器不能隐藏getter
通过给getter添加private访问修饰符实现只读索引器也只能在类中实现,结构体中getter必须能被外界访问到
使用添加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; }
}
同属性一样,派生类在实现索引器的时候也有两种选择:
可以为索引器添加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
请按任意键继续. . .
直接在索引器前添加接口名称,删除访问修饰符,进行显示接口实现
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;
}
}
以上,就是关于索引器的一些内容,不足之处还请指教,下面列出一些使用索引器的注意事项,供大家使用时参考:
通过索引器传递进来的值会传递给value变量,value的类型必须与索引器的类型相同
索引器不能作为ref或者out参数使用,数组可以
索引器只属于对象,不能使用static进行修饰
结构体中也可以使用属性,但是使用时结构体需要使用关键字new进行初始化,因为索引器只属于对象
索引器和属性很相似,属于有参的属性,使类或者结构体可以访问像数组一下访问数据
使用索引器获取数据或者修改数据,接收或者传递的值的类型必须与索引器的类型相同
索引器和属性相同,也可以通过隐藏get或者set访问器来实现只读索引器或者只写索引器,但是在结构体中必须保留get访问器,类中可以选择性的隐藏
索引器的只读或者只写也可以通过给get或者set访问器添加合适的访问修饰符private来实现,但是在结构体中get访问器不能设为私有的或者被保护的,只能为public类型的
PS:以上均是自己学习之后理解所写,水平有限难免会出现错误之处,总是唯恐给阅读到小伙伴造成误导,所以希望能够以质疑的态度去浏览,也希望小伙伴能够批评指出,共同成长。
C#中的索引器(Indexers)的更多相关文章
- C#中的索引器原理
朋友们,还记得我们在C#语言开发中用到过索引器吗? 记得在获得DataGridView控件的某列值时:dgvlist.SelectedRows[0].Cells[0].Value; 记得在获得List ...
- C#中的索引器的简单理解和用法
索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,使程序看起来更为直观,更容易编写. 1.索引器的定义 C#中的类成员可以是任意类型,包括数组和集合.当一个类包含了数组和集合成员时,索引器 ...
- C#中的索引器
在Java中,一般会这样使用get,set方法: class Person{ private String name; public void setName(String name){ this.n ...
- C# 接口中的索引器
索引器可在 接口(C# 参考) 上声明.接口索引器的访问器与类索引器的访问器具有以下方面的不同: 接口访问器不使用修饰符. 接口访问器没有体. 因此,访问器的用途是指示索引器是读写.只读还是只写.以下 ...
- 描述一下C#中索引器的实现过程,是否只能根据数字进行索引?
不是.可以用任意类型. 索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,使程序看起来更为直观,更容易编写. 1.索引器的定义 C#中的类成员可以是任意类型,包括数组和集合.当一个类包含了 ...
- C# 中常用的索引器
使用 C# 中的索引器和 JavaScript 中访问对象的属性是很相似. 之前了解过索引器,当时还把索引器和属性给记混了, 以为索引器就是属性,下面写下索引器和属性的区别,以及怎么使用索引器 先说明 ...
- C# 索引器,实现IEnumerable接口的GetEnumerator()方法
当自定义类需要实现索引时,可以在类中实现索引器. 用Table作为例子,Table由多个Row组成,Row由多个Cell组成, 我们需要实现自定义的table[0],row[0] 索引器定义格式为 [ ...
- 索引器(C# 编程指南)
原文地址:https://msdn.microsoft.com/zh-cn/library/6x16t2tx(VS.80).aspx 索引器允许类或结构的实例按照与数组相同的方式进行索引.索引器类似于 ...
- C# 索引器简介
索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,是程序看起来更为直观,更容易编写. 1.索引器的定义 C#中的类成员可以是任意类型,包括数组和集合.当一个类包含了数组和集合成员时,索引器 ...
随机推荐
- hadoop关闭安全模式
执行以下语句即可 hadoop dfsadmin -safemode leave
- 题解 [51nod1771] 最小生成树中的边
题面 解析 这题好像没人写过啊(所以好像没题解)... 然后刚了一天才写出来摆了半天. 其实一开始是想错了, 写了个\(O(n^2)\)的近似于暴力的方法. 就是对于每组权值相等的边, 对于每条边先把 ...
- 爬当当网上python书籍的图片
1.分析网页代码,获取图片下载连接:http://img3m4.ddimg.cn/20/11/23473514-1_b_5.jpg 2. python实现代码 import os import re ...
- Java 显示调用隐式调用
当你没有使用父类默认的构造方法时,此时在子类的构造方法中就需要显示的调用父类定义的构造方法.比如:父类:class Animal{ private String name; //如果你定义一个新的构造 ...
- 010_linuxC++之_运算符重载
(一)运算符重载:运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型. (二)实现类不同对象里中变量的相加 (三)程序 #include <iostream> ...
- 二维DFT
学习DIP第4天 傅里叶变换数学原理会在后续完整介绍,目前只实现代码,观察下结果,公式在上一篇博客中已经描述 内容迁移至 http://www.face2ai.com/DIP-2-2-二维DFT/ h ...
- 快速掌握Python的捷径-Python基础前传(1)
文: jacky(朱元禄) 开文序 最近看新闻,发现高考都考Python了,随着人工智能的火热,学数据科学的人越来越多了!但对于数据行业本身来说,现象级的火热,这并不是什么好事. 方丈高楼平地起,无论 ...
- 【java设计模式】-07适配器模式
适配器模式 定义: 将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 类型: 结构型模式 应用实例: 1.JAVA JDK 1.1 提供 ...
- Docker容器常用命令汇总
Docker常用命令总结如下: # 查看docker详细信息 docker info # 获取当前节点所有容器 docker ps -a # 管理容器生命周期 docker [start|stop|r ...
- eclipse异常:Exception in thread ""http-bio-8080"-exec-5" java.lang.OutOfMemoryError: PermGen space
用eclipse运行项目,最烦的就是非代码错误.现在这个异常信息,表示的是tomcat启动内存溢出.试过的最简单的办法就是eclipse->project->clean->clean ...