使用內嵌陣列宣告解決錯誤和警告
本文涵蓋下列編譯器錯誤和警告:
- CS9164: 無法將運算式轉換成
Span<T>
,因為它不是可指派的變數 - CS9165: 無法將運算式轉換成
ReadOnlySpan<T>
,因為可能不會以傳址方式傳遞或傳回運算式 - CS9166: 索引超出內嵌陣列界限
- CS9167: 內嵌陣列長度必須大於0。
- CS9168: 內嵌陣列結構不得有明確的配置。
- CS9169: 內嵌陣列結構必須宣告一個,而且只能宣告一個執行個體欄位,不能是參考欄位。
- CS9172: 內嵌陣列型別的元素只能使用可隱式轉換成
int
、System.Index
或System.Range
的單一引數來存取。 - CS9173: 內嵌陣列存取不得有具名引數指定名稱
- CS9180: 內嵌陣列元素欄位不可宣告為必要、唯讀、易變或固定大小緩衝區。
- CS9181: 內嵌陣列索引子不會用於元素存取運算式。
- CS9182: 內嵌陣列 'Slice' 方法不會用於元素存取運算式。
- CS9183: 內嵌陣列轉換運算子不會用於從宣告類型的運算式轉換。
- CS9184: 元素欄位是 '
ref
' 欄位,或是具有型別引數無效的類型之內嵌陣列型別不支援「內嵌陣列」語言功能。 - CS9189:
foreach
不支持型別內嵌陣列上的陳述式 - CS9259: 屬性 System.Runtime.CompilerServices.InlineArrayAttribute 無法套用至記錄結構。
內嵌陣列宣告
您可以將內嵌陣列宣告為具有單一欄位的 struct
型別,以及指定陣列長度的屬性。 編譯器會針對無效的內嵌陣列宣告產生下列錯誤:
- CS9167: 內嵌陣列長度必須大於 0。
- CS9168: 內嵌陣列結構不得有明確的配置。
- CS9169: 內嵌陣列結構必須宣告一個,而且只能宣告一個執行個體欄位,不能是參考欄位。
- CS9180: 內嵌陣列元素欄位不可宣告為必要、唯讀、易變或固定大小緩衝區。
- CS9184: 元素欄位是 '
ref
' 欄位,或是具有型別引數無效的類型之內嵌陣列型別不支援「內嵌陣列」語言功能。 - CS9259: 屬性 System.Runtime.CompilerServices.InlineArrayAttribute 無法套用至記錄結構。
若要修正這些陣列,請確定下列為 true:
- System.Runtime.CompilerServices.InlineArrayAttribute 的引數是正整數。
- 附上的
struct
不會指定任何明確的配置。 - 附上的
struct
具有單一執行個體欄位,而且該執行個體欄位不是ref
欄位。 - 單一執行個體欄位不是固定大小緩衝區。
- 單一執行個體欄位不包含
required
、volatile
或readonly
修飾元。 record
從內嵌數位宣告中移除 修飾詞。
項目存取
您可以使用與任何陣列相同的方式存取內嵌陣列的元素。 編譯器會從不正確的元素存取發出下列錯誤:
- CS9166: 索引超出內嵌陣列界限
- CS9172: 內嵌陣列型別的元素只能使用可隱式轉換成
int
、System.Index
或System.Range
的單一引數來存取。 - CS9173: 內嵌陣列存取不得有具名引數指定名稱
- CS9189:
foreach
不支持型別內嵌陣列上的陳述式
此外,當您宣告 索引子 時,編譯器會發出下列警告:
- CS9181: 內嵌陣列索引子不會用於元素存取運算式。
內嵌緩衝區產生的程式碼會略過任何宣告的索引子直接存取緩衝區記憶體。 內嵌陣列無法與 foreach
陳述式搭配使用。
索引子的引數必須是:
- 這三種型別之一:
int
、System.Index
或System.Range
。 - 不能是具名引數。 編譯器會產生元素存取子。 參數沒有名稱,因此您無法使用具名引數。
- 包含在陣列的界限中。 如同所有 .NET 陣列,內嵌陣列元素存取會進行界限檢查。 索引必須位於內嵌陣列的界限內。
轉換至 Span
您通常會使用 System.Span<T> 或 System.ReadOnlySpan<T> 來處理內嵌陣列。 編譯器會針對無效的轉換產生下列錯誤:
- CS9164: 無法將運算式轉換成
Span<T>
,因為它不是可指派的變數 - CS9165: 無法將運算式轉換成
ReadOnlySpan<T>
,因為可能不會以傳址方式傳遞或傳回運算式
編譯器會產生直接存取內嵌緩衝區內記憶體的程式碼。 因此,不會呼叫某些成員。 如果您撰寫其中一個從未呼叫的成員,編譯器會產生下列警告:
- CS9182: 內嵌陣列 'Slice' 方法不會用於元素存取運算式。
- CS9183: 內嵌陣列轉換運算子不會用於從宣告類型的運算式轉換。
內嵌陣列可隱式轉換成 Span<T>
或 ReadOnlySpan<T>
以將內嵌陣列傳遞至方法。 編譯器會對這些轉換強制執行限制:
- 內嵌陣列必須可寫入,才能將內嵌陣列轉換成
Span<T>
。 如果陣列是唯讀的,您無法將它轉換成可寫入的Span<T>
。 您可以改用ReadOnlySpan<T>
。 - 內嵌陣列的 安全內容 至少必須和
Span<T>
或ReadOnlySpan<T>
的 安全內容 一樣寬,轉換才會成功。 您必須限制跨度的內容,或展開內嵌陣列的範圍。
此外,編譯器永遠不會在內嵌緩衝區中產生 Slice
方法的呼叫。 未呼叫將內嵌緩衝區轉換成 Span
或 ReadOnlySpan
的轉換運算子。 編譯器會產生程式碼,以直接從記憶體緩衝區建立 System.Span<T> 或 System.ReadOnlySpan<T>。