「C#点滴」 更加优雅地访问序列数据:索引和范围

在 C# 8 之前,要实现诸如“访问序列倒数第二个元素””获取由第三个至第五个元素之间的元素组成的新序列”之类的功能是比较麻烦的,不够简洁直观。对此,C# 8 引入了索引和范围概念,极大简化了此类操作。

索引

C# 8 引入了新类型 System.Index 用于表示序列的索引,可以直接由 int 类型自动转换赋值。

int[] fibSequence = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 }; // 代表第3个元素的索引,起始索引为 0 Index index1 = 2; // 输出: 2 Console.WriteLine(fib)

看到这儿,性急的小伙伴应该要骂娘了,这不是多此一举嘛!直接用数字索引访问不是更好?

别着急,慢慢来,我们还可以在索引前面加 ^ 从后往前索引。

int[] fibSequence = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 }; // 第3个 Index index1 = 2; // 第5个 Index index2 = 5; // 倒数第1个 Index index3 = ^1; // 倒数第3个 Index index4 = ^3; // 输出:55 Console.WriteLine(fibSequence[index3]); // 输出:21 Console.WriteLine(fibSequence[index4]);

可以看出 ^n 实际上等同于 sequence.Length – n,因为数组的最后一个元素的索引是 sequence.Length – 1,因此 n = 0 时会报错,即 ^0 访问单个元素时会报错。

嗯,现在感觉有点意思了,但是不是有点繁琐呢,还要申明一个 Index 类型的变量才能用。其实不用,我们之所以写出来,是因为强调其背后的数据类型为新引入的 System.Index,实际中直接使用字面量即可。

int[] fibSequence = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 }; // 倒数第1个:55 Console.WriteLine(fibSequence[^1]); // 倒数第2个:21 Console.WriteLine(fibSequence[^2]); // 倒数第0个:报错 Console.WriteLine(fibSequence[^0]);

范围

C# 8 引入了新类型 System.Range 表示序列的一部分,表达形式为 起始索引..结束索引。

int[] fibSequence = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 }; // {2,3} var subSequence1 = fibSequence[2..4]; // {3,5} var subSequence2 = fibSequence[3..5]; // { 1, 1, 2, 3, 5, 8, 13, 21, 34 } var subSequence3 = fibSequence[0..^1];

可以看出,结束索引不包括在结果中。2..4 实际上包含 fibSequence[2] 到 fibSequence[3]的值。以此类推, 0..^1 包含fibSequence[0] 到 fibSequence[^2]的值, 缺少最后一个元素。要表示整个范围,可以用 0..^0 。

开始索引和结束索引可以省略。

int[] fibSequence = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 }; // 等同 5..^0 :{ 8, 13, 21, 34, 55 } var subSequence1 = fibSequence[5..]; // 等同 0..^5 : { 1, 1, 2, 3, 5 } var subSequence2 = fibSequence[..5]; // 全部,等同于 0..^0 var subSequence3 = fibSequence[..];

### 类型支持

索引和范围的支持不限于数组,方式包括显示支持和隐式支持。

显式支持

通过实现带 Index 或者 Range 类型参数的索引器来显式支持索引或范围。

public class ExplicitIndexAndRange { private List _list = new(); /// /// 显示索引,通过带 Index 类型参数的索引器实现 /// public int this[Index index] { get { var idx = index.IsFromEnd ? _list.Count – index.Value : index.Value; if (idx = _list.Count) { return -1; } return _list[idx]; } } /// /// 显示支持范围,通过带 Range 类型参数的索引器实现 /// public List this[Range range] { get { var sIdx = range.Start; var eIdx = range.End; var startIndex = sIdx.IsFromEnd ? _list.Count – sIdx.Value : sIdx.Value; var endIndex = eIdx.IsFromEnd ? _list.Count – eIdx.Value : eIdx.Value; var newList = new List(); for (int i = startIndex; i < endIndex; i++) { newList.Add(_list[i]); } return newList; } } }

隐式支持索引

满足以下条件,编译器自动添加索引支持。

  • 具有一个返回 int 值的 Length 或者 Count 属性
  • 具有可访问的实例索引器,该索引器采用单个 int 作为参数
  • 没有显式实现索引器

public class ImplicitIndexAndRange { private List _list = new(); /// /// 实现 Length 或者 Count 属性,必须返回 int 类型值 /// public int Count => _list.Count; /// /// 实现 int 索引器 /// public int this[int index] { get { if (index = Count) { return -1; } return _list[index]; } } }

Range 隐式支持

满足以下条件,编译器自动添加索引支持。

  • 具有一个返回 int 值的 Length 或者 Count 属性
  • 具有可访问方法 Slice ,它具有两个类型为 int 的参数
  • 没有显式实现范围

public class ImplicitIndexAndRange { private List _list = new(); /// /// 实现 Length 或者 Count 属性,必须返回 int 类型值 /// public int Count => _list.Count; /// /// Slice,省略了长度检查异常处理 /// public int[] Slice(int start, int length) { var slice = new int[length]; for (var i = start; i < start + length; i++) { slice[i] = _list[i]; } return slice; } }

郑重声明:本文内容及图片均整理自互联网,不代表本站立场,版权归原作者所有,如有侵权请联系管理员(admin#wlmqw.com)删除。
(0)
用户投稿
上一篇 2022年6月21日
下一篇 2022年6月21日

相关推荐

  • 继邓刚天元之后,曾大盆战队宣布退出王者之战

    邓刚和天元的退赛,并不意味着本届王者之战的混乱结束,而只是开始:今天,曾大盆代表他的团队官宣,退出王者之战。 原以为主办方是王者,可以主导一切,可在自媒体发达的今天,显然不是。 本…

    2022年8月24日
  • Python queue 模块详解

    queue 模块即队列,特别适合处理信息在多个线程间安全交换的多线程程序中。下面我们对 queue 模块进行一个详细的使用介绍。 queue 模块定义的类和异常 queue 模块定…

    2022年6月29日
  • 信通院公布数字政府最新评估结果 天翼云通过两项权威评估

    8月10-12日,由中国信息通信研究院(以下简称“中国信通院”)、中国通信标准化协会主办的“2022数字化转型发展高峰论坛”在北京举办。本次论坛以“数字原生、产业新生、价值共生”为…

    2022年8月15日
  • 不想天天穿裙子?那就考虑优雅温柔的套装吧

    不想天天穿裙子?那就试试两件套吧,省去烦人的搭配问题,轻轻松松完美出门! 棉麻简约两件套,腰部的收腰设计真的非常特别,巧妙遮肉又时尚好看,上衣独特气质,百搭简约裤子,整体效果优雅知…

    2022年7月25日
  • 王心凌薛凯琪被赞青春,张嘉倪却被嘲扮嫩?如何自然凹出少女感?

    因为大环境的审美导向,我们内娱的女明星都爱“少女感”,无论长相御姐还是长相甜美都偏爱少女感,但是即使是有专业造型团队的明星也容易走入少女感误区,被广大网友吐槽扮嫩,这一期我们就来聊…

    2022年6月9日
  • 欧洲五强英德法意俄近31年(1991-2021)GDP对比数据

    单位:万亿美元 主要轨迹: 1.英法两国与德国差距大幅度缩小,背后一个原因是两国人口增速远超德国; 2.英法两国GDP交叉4次,背后是欧盟与英美实力的较量; 3.意大利已经和英法不…

    2022年8月1日
  • 升级加速 病理数字化正当时

    王查娜 “在临床医学中,病理诊断是最需要智能化的专业之一。病理在临床诊断中提供的诊断价值最大,但智能化难度也是最大的。”在近日举办的第六届未来医疗百强大会之AI辅助诊断创新发展分论…

    2022年7月12日
  • 哈登俩年续约76人,最关键的是合同数据真狠啊

    哈登俩年续约76人,最关键的是合同数据真狠啊! 登哥新赛季比原来薪资降了1500万,我就想问问登哥,你放弃这么多钱值得吗,但哈登不后悔为了冠军可以牺牲一切,这就叫倾其所有吧。 上赛…

    2022年7月21日
  • 女人到了中年,穿衣打扮要“得体”,更要学会不扮嫩也不放任老态

    上了年纪的女人们一定不能忘中年穿衣的大忌:年龄和穿衣风格千万别“对不上号”!仔细想想,小年轻穿过于成熟的服装,会被人说故作老成;而上了年纪的人再去穿小女孩的公主裙、松糕鞋,就更会被…

    2022年6月12日
  • C++|宽窄基本类型转换和父类子类转换

    基本数据类型有不同的编码方案(encoding scheme),需要不同的字节长度来适应各自的值域。 基本类型的宽窄转换,是一个整体的转换,其由窄到宽是安全的,由宽到窄可能会丢失数…

    2022年6月13日

联系我们

联系邮箱:admin#wlmqw.com
工作时间:周一至周五,10:30-18:30,节假日休息