前言
在《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、使用^和..這兩個語法糖,讓代碼更加干凈,可讀,易維護
優秀是一種習慣,歡迎大家關注學習

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/253312.html
標籤:.NET Core
