说说C# 8.0 新增功能Index和Range的^0是什么?
前言
在《C# 8.0 中使用 Index 和 Range》这篇中有人提出^0是什么意思?处于好奇就去试了,结果抛出异常。查看官方文档说^0索引与 sequence[sequence.Length] 相同,表达式 sequence[^0] 不会引发异常,就像 sequence[sequence.Length] 一样。但是在实际使用[^0]的时候抛出IndexOutOfRangeException的异常,很疑惑究竟是什么原因?
先说一下 C# 8.0 新增的两个新类型和两个新运算符,允许构造System.Index和System.Range对象,并在运行时索引/切片集合。
一、System.Index和System.Range结构
1、Index
表示一种可用于从开头或从结尾索引集合的类型。
public struct Index : IEquatable<Index>
示例代码
string [] myArray = new string[5] { "A", "B", "C", "D", "E" };
string strArray= myArray[^1]; // strArray = E
代码中使用末尾运算符^和Index类型,myArray[ ^1] 表示从数组的倒数第一个元素,也就是从末尾开始算的第一个元素,所以最终结果是:E。
Hat运算符(^)的索引,指定一个索引与序列末尾相关。
2、Range
表示具有起始索引和结束索引的范围。
public struct Range : IEquatable<Range>
示例代码
string[] myArray = new string[5] { "A", "B", "C", "D", "E" };
string[] strArray = myArray[0..2]; // { A, B }
代码中使用范围运算符(..)和Range类型,myArray[0..2]表示把myArray这个序列,从索引为0的元素一直找到索引为2(但不包括索引2)的元素提取出来组成新的数组,所以最终结果是: {A,B}。
范围运算符(..),用于指定范围的开始和末尾,就像操作数一样。
Range类型范围运算符包含start不包含end。eg:myArray[0..2]包含索引0不包含索引2
3、Index和Range组合使用
尝试在Range的两端混合使用"从开始"和"从末尾"的Index,看看会发生什么?
var strNum = new string[]
{
// index from start index from end
"A", // 0 ^9
"B", // 1 ^8
"C", // 2 ^7
"D", // 3 ^6
"E", // 4 ^5
"F", // 5 ^4
"G", // 6 ^3
"H", // 7 ^2
"I" // 8 ^1
}; // 9 (strNum.Length) ^0
foreach (var item in strNum[0..^1])
Console.Write($"{item}");
foreach (var item in strNum[1..^0])
Console.Write($"{item}");
foreach (var item in strNum[0..^0])
Console.Write($"{item}");
输出结果:
ABCDEFGH
BCDEFGHI
ABCDEFGHI
0..^1 与 ..^1 相同 表示从0索引位置到末尾开始算的第1个元素
1.. 与 1..^0 相同 表示从1索引位置到末尾开始算的第0个元素
.. 与 0..^0 相同 表示全部从头到尾
二、[^0]会抛异常
1、[^1] 示例代码
int[] myArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int num = myArray[^1]; //num=10
2、[^0]示例代码
int[] myArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int num = myArray[^0]; //抛异常
代码结果如下图所示:

官方文档描述:请考虑数组 sequence。 0 索引与 sequence[0] 相同。 ^0 索引与 sequence[sequence.Length] 相同。 表达式 sequence[^0]不会引发异常,就像 sequence[sequence.Length] 一样。 对于任何数字 n,索引 ^n 与 sequence[sequence.Length - n] 相同。
通过自己搜索到合理的解释 Index 类型 从尾部开始的索引是从1开始的,与序列的长度相关,那么意思就说单独使用末尾运算符时索引只能从1开始。
三、遗留问题
使用末尾运算符时索引只能从1开始,但是Index和Range组合使用时可以从0开始,目前还没有找到具体原因,如果大家有好的解释和方法,欢迎留言沟通和交流。
四、总结
1、Range类型 运算符(..)包括Start不包括End
2、Index类型 末尾运算符(^)
· 从头开始的索引是从0开始的
· 从尾部开始的索引是从1开始的,与序列的长度相关
3、减少 SubString 的使用,eg:var str="12345"截取后三位,之前写法str.Substring(2,3),新语法str[^3..]
4、使用^和..这两个语法糖,让代码更加干净,可读,易维护
优秀是一种习惯,欢迎大家关注学习

说说C# 8.0 新增功能Index和Range的^0是什么?的更多相关文章
- C#基础拾遗系列之二:使用ILSpy探索C#7.0新增功能点
C#基础拾遗系列之二:使用ILSpy探索C#7.0新增功能点 第一部分: C#是一种通用的,类型安全的,面向对象的编程语言.有如下特点: (1)面向对象:c# 是面向对象的范例的一个丰富实现, 它 ...
- C#2.0新增功能06 协变和逆变
连载目录 [已更新最新开发文章,点击查看详细] 在 C# 中,协变和逆变能够实现数组类型.委托类型和泛型类型参数的隐式引用转换. 协变保留分配兼容性,逆变则与之相反. 以下代码演示分配兼容性.协 ...
- C#基础拾遗系列之二:C#7.0新增功能点
第一部分: C#是一种通用的,类型安全的,面向对象的编程语言.有如下特点: (1)面向对象:c# 是面向对象的范例的一个丰富实现, 它包括封装.继承和多态性.C#面向对象的行为包括: 统一的类型系统 ...
- C#7.0新增功能点
原文地址: https://www.cnblogs.com/runningsmallguo/p/8972678.html 第二部分:C#7.0新增的功能 (1)数字字面量的提升: C#7中的数字文字 ...
- C#2.0新增功能01 分布类与分部方法
连载目录 [已更新最新开发文章,点击查看详细] 分部类型 拆分一个类.一个结构.一个接口或一个方法的定义到两个或更多的文件中, 每个源文件包含类型或方法定义的一部分,编译应用程序时将把所有部分组 ...
- Android 7.0 新增功能和api
Android 7.0 Nougat 为用户和开发者引入多种新功能.本文重点介绍面向开发者的新功能. 请务必查阅 Android 7.0 行为变更以了解平台变更可能影响您的应用的领域. 要详细了解 A ...
- C#8.0 新增功能
连载目录 [已更新最新开发文章,点击查看详细] C#8.0提供了许多增强功能 01 Readonly 成员 可将 readonly 修饰符应用于结构的任何成员. 它指示该成员不会修改状态. 这比 ...
- C#7.0 新增功能
连载目录 [已更新最新开发文章,点击查看详细] C# 7.0 向 C# 语言添加了许多新功能 01 out 变量 支持 out 参数的现有语法已在此版本中得到改进. 现在可以在方法调用的参数列表 ...
- Xcode 9.0 新增功能大全
Xcode是用于为Apple TV,Apple Watch,iPad,iPhone和Mac创建应用程序的完整开发人员工具集.Xcode开发环境采用tvOS SDK,watchOS SDK,iOS SD ...
随机推荐
- Python编程基础:循环结构
一.为什么要用循环 现在有一个任务,要求你输出一百遍"好好学习,天天向上!",想一想,你会怎么做? (一)老老实实的笨方法 print("第1遍写:好好学习,天天向上!& ...
- Python(循环语句与数据类型)
循环语句 对于python来说 基本上循环用的两个 wile 跟静态语言相似 下来是for循环 这个就跟静态语言大大不同了 wile 条件:–>while 循环也就是 当条件为真的时候会一直循环 ...
- 分布式事务MSDTC使用时,需要的配置
服务器最终配置 DTC服务 组件 防火墙 这里,跟下面的解决方案有点差异,在添加2个规则之后,原本就有分布式相关的规则,也给开启了. 网上的解决办法 在服务里打开 Distributed Transa ...
- 在Linux下面端口映射socat自动脚本
这个sh脚本可以方面的端口映射,在使用本功能之前请确保socat已经放到了/usr/bin/socat #!/bin/bash cd `dirname $0` let listenport=`base ...
- win7激活不支持的启动引导分区完美解决方法
前言: 激活win7显示不支持的启动引导分区怎么办?有用户使用暴风激活工具给win7 64位系统激活时,弹出Error提示框"不支持的启动引导分区". 这是因为传统的win7激活工 ...
- java面试 题
分布式消息队列 1,为什么使用消息队列啊消息队列有什么优点和缺点啊 2,如何保证消息队列的高可用啊如何保证消息不被重复消费啊 3,kafka,activemq,rabbitmq,rocketmq都有什 ...
- JavaScript 获取数组对象中某一值封装为数组
1.获取数组对象中某一值封装为数组(一) data = [["2000-06-05",116],["2000-06-06",129]]; var dateLis ...
- [leetcode]48RotateImage二维数组翻转
import java.util.Arrays; /** * You are given an n x n 2D matrix representing an image. Rotate the im ...
- leetcode 274H-index
public int hIndex(int[] citations) { /* 唠唠叨叨说了很多 其实找到一个数h,使得数组中至少有h个数大于等于这个数, 其他N-h个数小于这个数,h可能有多个,求最 ...
- JavaDailyReports10_10
1.4.2 键盘事件的处理 KeyListener 接口实现了处理键盘事件 KeyEvent 对象描述键盘事件的相关信息. KeyListener 接口有三个方法:KeyPressed K ...