1. 程式人生 > >C# 中 System.Index 結構體和 Hat 運算子(^)的全新用法

C# 中 System.Index 結構體和 Hat 運算子(^)的全新用法

> 翻譯自 John Demetriou 2019年2月17日 的文章 [《C# 8 – Introducing Index Struct And A Brand New Usage For The Hat Operator》](http://www.devsanon.com/c/c-8-introducing-index-struct-and-a-brand-new-usage-for-the-hat-operator/) 今天我們要講的是 Hat 運算子(`^`)。目前為止,Hat 運算子(`^`)已經被用作布林型別的異或運算子,以及位元組、整型型別的按位異或運算子。在 C# 8 中,它有一個新的用法。 這個運算子的新用法是*自動建立 `Index` 結構體的例項*。那什麼是 `Index` 結構呢?這在 C# 8 中也有介紹。 `Index` 結構體的程式碼(就像所有的 C# 程式碼一樣)可以[在 github 上找到](https://github.com/dotnet/coreclr/blob/88eb93abba27e97d5997ad2d6c04b54aeaff5e8f/src/System.Private.CoreLib/shared/System/Index.cs)。你可以看到,它是一個相當簡單的結構體,包含一個整數值,和一個定義是否應該從末尾開始計數的布林值。 它有助於讓訪問陣列比以往容易很多。我們可以很輕鬆地將這個值儲存在一個 `Index` 型別中來代替一個整數,它比一個簡單的整數更清楚地定義了我們的意圖,並有助於避免該變數的誤用。 到目前為止,當嘗試訪問陣列中特定索引處的值時,我們總是從第一個元素開始考慮。那麼 Hat 運算子(`^`)是如何幫助我們的呢?例如,如果你想獲取一個已知大小的陣列的最後一個元素,你通常會從陣列的 Length 中減去 1,並在檢索時使用這個技巧或硬編碼的數字。 例如: ```csharp int[] array = new int[] { 1, 3, 5, 7, 9 }; var x = array[4]; ``` 你可以像下面的例子一樣使用陣列提供的變數: ```csharp int[] array = new int[] { 1, 3, 5, 7, 9 }; var x = array[array.Length - 1]; ``` 這種方法也可以用於編譯時長度未知的陣列。並且這通常是首選方法,因為它表明您希望更容易地檢索最後一項,而不是必須進行計數來檢視哪個是第四項並驗證它是最後一項。 適當的使用 `Index` 結構,我們可以很容易地建立一個索引值型別,這樣我們就可以儲存它並隨心地重用它,以避免違反 DRY 原則。 ```csharp Index lastItem = new Index(4, false); int[] array = new int[] { 1, 3, 5, 7, 9 }; var x = array[lastItem]; ``` > 譯者注: > DRY 是 “Don't repeat yourself” 的縮寫,是軟體開發的一個原則,旨在減少軟體模式的重複,用抽象來替代它,或者使用資料規範化來避免冗餘。也就是說,在一個設計裡,對於任何東西,都應該有且只有一個表示,其它的地方都應該引用這一處。這樣需要改動的時候,只需調整這一處,所有的地方就都變更過來了。 但正如我們所看到的,我們還可以使用 fromEnd 引數來更好地表達我們希望檢索最後一項,並在編譯時從一個大小未知的陣列中檢索最後一項。 ```csharp Index lastItem = new Index(1, true); int[] array = new int[] { 1, 3, 5, 7, 9 }; var x = array[lastItem]; ``` 不過,我們需要記住的一點是,當從末尾開始計數時,不是以 0 開始的索引。把它想象成我們使用的 `Length - x` ,其中 **`x`** 就是我們在 `Index` 結構體建構函式中使用的值。 但是 Hat 運算子(`^`)在這一切中有何用武之地呢?唔,Hat 運算子(`^`) 是呼叫 `Index` 結構體時將 fromEnd 設定為 true 的簡寫方式。 比如,下面的兩行是完全相同的: ```csharp Index lastItem = new Index(1, true); // line 1 int[] array = new int[] { 1, 3, 5, 7, 9 }; var x = array[lastItem]; Index lastItem = ^1; //line 2, 同 line 1 int[] array = new int[] { 1, 3, 5, 7, 9 }; var x = array[lastItem]; ``` 或者,如果你想要檢索倒數第二項,你可以這麼做: ```csharp Index secondToLast = new Index(2, true); int[] array = new int[] { 1, 3, 5, 7, 9 }; var x = array[secondToLast]; Index secondToLast = ^2; int[] array = new int[] { 1, 3, 5, 7, 9 }; var x = array[secondToLast]; ``` 就這樣,一個新的結構體型別和一箇舊運算子(`^`)的新用法打包在一起了。
`System.Index` 結構體,與 `System.Range` 結構體是攜手並進的,您可以點選[這裡檢視 https://www.cnblogs.com/ittranslator/p/13800588.html](https://www.cnblogs.com/ittranslator/p/13800588.html)。
> 作者 : [John Demetriou](https://www.devsanon.com/whoami/) > 譯者 : 技術譯民 > 出品 : [技術譯站](https://ittranslator.cn/) > 連結 : [英文原文](http://www.devsanon.com/c/c-8-introducing-index-struct-and-a-brand-new-usage-for-the-hat-ope