前言

对于索引器,我们肯定不会陌生。为什么会有索引器这个东西呢?我们发现这东西很像是属性,只是通过索引方式去调用,那就慢慢揭开他的面纱吧。

正文

假设我们要对外暴露一个数组,为了体现其封装性,我们使用数组。

public Class Instance{
public int[] IntArr{get;set;}
}

这样似乎就可以了,但是有个问题,那就是假如我要取得是其中的一个值。

那么可以这样写instance.IntArr[0],这样写似乎没得啥子问题呢,但是运行过程是instance.IntArr 会创建一个匿名对象,然后再取其中的索引0。

这样似乎是不必要的。

然后索引器可以这样:

public Class Instance{
private int[] intArr;
public int this[int index]
{
get { return intArr[index]; }
set { intArr[i]=value; }
}
}

那么调用方式是这样的:instance[i]。

这种方式比较简单,很多情况下都是不希望知道内部怎么实现的,比如说索引是一个string,传递的值需要经过某种计算然后得出。

比如说官网给出一个例子:

using System;
// Using a string as an indexer value
class DayCollection
{
string[] days = { "Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat" }; // Indexer with only a get accessor with the expression-bodied definition:
public int this[string day] => FindDayIndex(day); private int FindDayIndex(string day)
{
for (int j = 0; j < days.Length; j++)
{
if (days[j] == day)
{
return j;
}
} throw new ArgumentOutOfRangeException(
nameof(day),
$"Day {day} is not supported.\nDay input must be in the form \"Sun\", \"Mon\", etc");
}
}

通过这种模式实现一个类数组的结构,会使我们的代码简洁很多。

索引还是和属性用法还是不同的,索引只能是实例成员。我也不知道为什么要这样设计,但是我是这样想得,加上其不是一个实例成员,而是一个静态成员,似乎是没有任何意义的,因为我没

有找到任何这样的意义。

值得注意的是,接口中依然存在索引。

官网给出的例子是:

// Indexer on an interface:
public interface IIndexInterface
{
// Indexer declaration:
int this[int index]
{
get;
set;
}
} // Implementing the interface.
class IndexerClass : IIndexInterface
{
private int[] arr = new int[100];
public int this[int index] // indexer declaration
{
// The arr object will throw IndexOutOfRange exception.
get => arr[index];
set => arr[index] = value;
}
}

和接口定义的规则一样,在接口中我们不能去做具体的试下,只需定义即可。

因为接口可以继承,那么可能会形成属性冲突,那么具体实现的时候就需要:

public int IIndexInterface.this[int index]   // indexer declaration
{
// The arr object will throw IndexOutOfRange exception.
get => arr[index];
set => arr[index] = value;
}

系列持续更新中。

重学c#系列——索引器(十)的更多相关文章

  1. 重学c#系列——字典(十一)

    前言 重学c#系列继续更新,简单看一下字典的源码. 看源码主要是解释一下江湖中的两个传言: 字典foreach 顺序是字典添加的顺序 字典删除元素后,字典顺序将会改变 正文 那么就从实例化开始看起,这 ...

  2. 重学c#系列——linq(2) [二十八]

    前言 前文提及到了一些基础的linq的基础,那么这一节是一些补充. 正文 关于一个orderby的问题. 比如我们输入两个order by. 这里告诉我们多个order by是没有意义的,如果多个那么 ...

  3. 重学c#系列——对c#粗浅的认识(一)

    前言 什么是c#呢? 首先你是如何读c#的呢?c sharp?或者c 井? 官方读法是:see sharp. 有没有发现开发多年,然后感觉名字不对. tip:为个人重新整理,如学习还是看官网,c# 文 ...

  4. 重学c#系列——动态类型[二十二]

    前言 该系列准备继续完善,一共108篇,持续更新. 正文 为什么有动态类型呢? 是因为很多东西天生就是动态类型的. 比如xml 和 json.cvs.数据库表,这些本来就是数据类型的. 在反射系列中提 ...

  5. 重学c#系列——list(十二)

    前言 简单介绍一下list. 正文 这里以list为介绍. private static readonly T[] s_emptyArray = new T[0]; public List() { t ...

  6. 重学c#系列——linq(3) [二十九]

    前言 继续介绍一些复杂的linq. 正文 groupjoin 这个函数: 有department public class Deployment { public string Id { get; s ...

  7. 重学c#系列—— explicit、implicit与operator[三十四]

    前言 我们都知道operator 可以对我们的操作符进行重写,那么explicit 和 implicit 就是对转换的重写. 正文 explicit 就是强制转换,然后implicit 就是隐式转换. ...

  8. 重学c#系列——string.empty 和 "" 还有null[二十]

    前言 简单整理一下string.empty 和 "" 还有 null的区别. 正文 首先null 和 string.empty 还有 "" 是不一样的. nul ...

  9. 重学c#系列——逆变和协变[二十四]

    前言 简单整理一下逆变和协变. 正文 什么是逆变和协变呢? 首先逆变和协变都是术语. 协变表示能够使用比原始指定的派生类型的派生程度更大的类型. 逆变表示能够使用比原始指定的派生类型的派生程度更小的类 ...

  10. 重学c#系列——委托和匿名函数[二十五]

    前言 简单介绍一下什么是委托. 正文 以前也写过委托,这次算是重新归档,和新的补充吧. https://www.cnblogs.com/aoximin/p/13940125.html 有些人说委托是函 ...

随机推荐

  1. Java 接口:比较对象的大小

    1 package com.bytezreo.interfacetest; 2 3 /** 4 * 5 * @Description 接口:比较对象的大小 6 * @author Bytezero·z ...

  2. redis分片sharding实现原理

    为什么集群? 通常,为了提高网站响应速度,总是把热点数据保存在内存中而不是直接从后端数据库中读取.Redis是一个很好的Cache工具.大型网站应用,热点数据量往往巨大,几十G上百G是很正常的事儿,在 ...

  3. 当未指定且存在多个构造器,实例化对象时Spring如何选择?

    前言 在前面的讲解中,我们了解了如何获取构造器.当只有一个符合条件的构造器时,自然会选择它作为初始化的构造器.然而,在上一节中,我们遇到了一种特殊情况:当有多个符合条件的构造器时,返回的是一个数组.在 ...

  4. .NET Core 的 Docker 容器目录乱码问题

    现象 使用 docker exec -ti <容器名> bash 进入容器,使用 ls 命令列出的数据里面,中文没有正常显示. 原因 就是对应的 Shell 字符集不正确的问题,调整对应的 ...

  5. 学习ASP.NET Core Razor 编程系列文章目录

    学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二--添加一个实体 学习ASP.NET Core Razor 编程系列三--创建数据表及创建项目 ...

  6. 词根 ten 展开 持有 /tin/tent/tain “to hold”

    词根 ten 展开 持有 /tin/tent/tain "to hold" 记忆方式:en是拿出.忘了从哪里看的了.t是动作过去. 如果是 过去的时候已经拿出来,那就是 展开 延展 ...

  7. PE文件手工压缩

    序 本文要压缩的PE文件来自软件漏洞这门课上布置的作业,代码逻辑很简单,直接运行就能看出来,就是调库来弹两个对话窗口.笔者主要记录一下对这个文件的分析和一步步实现手工压缩的过程.在此提供原文件的下载方 ...

  8. buu第一页复盘

    这里就对之前第一遍没写出来的题目再写一次wp 写在之前 贴一下我的模块文件 from pwn import * from LibcSearcher import * from struct impor ...

  9. C++ bind函数

    bind()是一个函数适配器,返回一个可调用对象,他可以将一个函数的参数列表做魔改. 设置默认参数 using namespace std::placeholders; void f(int a, i ...

  10. 数据好合: Argilla 和 Hugging Face Spaces 携手赋能社区合力构建更好的数据集

    最近,Argilla 和 Hugging Face 共同 推出 了 Data is Better Together 计划,旨在凝聚社区力量协力构建一个对提示进行排名的偏好数据集.仅用几天,我们就吸引了 ...