翻譯自 John Demetriou 2020年4月6日 的文章 《C# 8 Is Introducing Ranges》html
咱們以前討論過的 C# 中的一個特性 System.Index 結構體[1],與另外一特性 System.Range 結構體 是攜手並進的。api
在 C# 8.0 以前,沒有訪問集合中任意部分的範圍或切片的語法。開發人員一般不得不執行一些自定義的切片操做,或者依靠諸如 array.Skip(5).Take(2);
的 LINQ 方法。數組
如今 C# 添加了一個新的小特性,它能夠幫助人們從一個大的數組項目中獲取一個小範圍的項目。ui
讓咱們來考慮一下。假設咱們有一個項目數組,咱們僅需展現其中的一部分。一般狀況下,咱們只須要循環這部分,而後像下面這樣輸出它們。spa
var array = new string[] { "Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9" }; for (int i = 1; i <= 5; i++) { Console.WriteLine(array[i]); }
所以當咱們僅須要幾個特定的項,咱們經過控制索引值來獲取它們。翻譯
經過使用範圍(Range
),咱們能夠用如下方式來替換:code
var array = new string[] { "Item0", "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9" }; foreach (var item in array[1..5]) { Console.WriteLine(item); }
在這裏,第一次使用的人會注意到一個奇怪的狀況——它只會打印四項。爲何呢?這是由於範圍(Range
)包含開始,但不包含末尾。
若是想要與上面的 for
循環有相同的結果,咱們的 foreach
循環應該是:htm
foreach (var item in array[1..6]) { Console.WriteLine(item); }
一、從索引 1(包含) 到末尾(包含)對象
foreach (var item in array[1..]) { Console.WriteLine(item); }
二、從開始(包含)到索引 3(不包含)blog
foreach (var item in array[..3]) { Console.WriteLine(item); }
三、結合以上兩種,您能夠獲得一個語法上正確的如下版本
foreach (var item in array[..]) { Console.WriteLine(item); }
它的意思是獲取整個範圍。
譯者注
它也等同於下面兩種寫法:
foreach (var item in array[0..^0]) { Console.WriteLine(item); }
foreach (var item in array[0..array.Length]) { Console.WriteLine(item); }
四、從索引 1(包含)到 從末尾開始的索引 1(不包含)
foreach (var item in array[1..^1]) { Console.WriteLine(item); }
在這裏,它結合了前面文章中介紹的 Index
的 Hat 運算符(^
)。
一個快速的解釋,Hat 運算符(^
),會給您一個特定的索引。若是您寫 ^1
,也就是在請求最後一項的索引。如上所述,考慮到最後一個索引號是排除的,在一個有 10 項的序列中,請求索引項直到 ^1
,您也就是在請求索引項直到索引 9(索引從 0 開始),而且該項不包括在其中。
我但願我講清楚了。
咱們前面所作的是,將範圍(Range
)做爲類型傳遞。咱們也能夠將範圍聲明爲一個變量:
Range range = 1..9;
而後,能夠在 [
和 ]
字符中使用該範圍:
var subarray = array[range];
咱們還能夠將其做爲方法的參數傳遞、將其存儲爲私有變量,或者用在任何業務邏輯所需的地方。
範圍(Range
)不能被用在 List
或者 IEnumerable<Τ>
,但數組並非惟一支持它的類型。
您還能夠將索引(Index
)和範圍(Range
) 與 String
、Span<T>
或 ReadOnlySpan<T>
一塊兒使用。
與字符串一塊兒使用的例子基本上就是代替 Substring
方法,以下所示:
string s = "01234567"; string r = s[1..3]; // r 將會是 "12"
對於每一個擔憂 List
(它多是您一般用來替代數組的類型)不支持範圍的人來講,List
從 .Net Framework 2.0 開始就已經有 GetRange
方法了。
如下爲譯者補充
索引(Index
)和範圍(Range
)爲訪問序列中的單個元素或範圍提供了簡潔的語法。
對索引和範圍的語言支持依賴於兩個新類型和兩個新運算符:
System.Index
類型表示一個序列索引。^
),指定一個索引與序列末尾相關,用於構造 System.Index
對象。System.Range
類型表示序列的子範圍。..
),用於指定範圍的開始和末尾,就像操做數同樣,用於構造 System.Range
對象。考慮數組 sequence
, 0
索引與 sequence[0]
相同。 ^0
索引與 sequence[sequence.Length]
相同。 請注意,sequence[..^0]
不會引起異常,就像 sequence[..sequence.Length]
同樣。對於任意數字 n
,索引 ^n
與 sequence.Length - n
相同。 以下面代碼中的註釋所示:
string[] words = new string[] { // index from start index from end "The", // 0 ^9 "quick", // 1 ^8 "brown", // 2 ^7 "fox", // 3 ^6 "jumped", // 4 ^5 "over", // 5 ^4 "the", // 6 ^3 "lazy", // 7 ^2 "dog" // 8 ^1 }; // 9 (or words.Length) ^0
一個範圍指定了範圍的「開始」和「末尾」。 範圍是左閉右開的,也就是說範圍包含「開始」,不包含「末尾」。
範圍 [0..sequence.Length]
、[0..^0]
和 [..]
都表示整個範圍。
做者 : John Demetriou
譯者 : 技術譯民
出品 : 技術譯站
連接 : 英文原文
http://www.javashuo.com/article/p-qqvmqtjv-nu.html "System.Index
結構體" ↩︎