首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> C# 入門

C# 陣列完整指南:一維/多維/交錯陣列、索引、迭代、陣列類別與 Span 效能

     編輯:C# 入門

C# 陣列完整指南:一維/多維/交錯陣列、索引、迭代、陣列類別與 Span 效能

陣列 是固定大小、同質元素的連續記憶體結構,是 .NET 最基礎的集合型別。陣列實作 IList<T>、IReadOnlyList<T>、IEnumerable<T>,提供隨機存取 O(1)、極佳快取局部性。本文涵蓋宣告、初始化、多維/交錯陣列、Array 類別方法、Span<T> 高效能切片。

一維陣列:宣告與初始化

// 宣告
int[] numbers;                    // 未初始化,值為 null
int[] numbers2 = new int[5];      // 預設值 0
int[] numbers3 = new int[] {1,2,3,4,5}; // 隱含大小
int[] numbers4 = {1,2,3,4,5};     // 簡寫 (僅宣告時)
var numbers5 = new[] {1,2,3};     // 型別推斷

// 索引存取 (0-based)
numbers2[0] = 10;
var first = numbers2[0];

// 陣列為參考型別
int[] a = {1,2,3};
int[] b = a;        // 同一參考
b[0] = 99;
Console.WriteLine(a[0]); // 99

// 複製陣列
int[] c = (int[])a.Clone();       // 淺層複製
int[] d = a.ToArray();            // LINQ 擴充方法
int[] e = new int[a.Length];
Array.Copy(a, e, a.Length);       // 低層複製
a.CopyTo(e, 0);                   // 實例方法

多維陣列

矩形陣列

所有維度大小固定,記憶體連續:

// 宣告: 2 維度,3列 4行
int[,] matrix = new int[3, 4];
int[,] matrix2 = { {1,2,3}, {4,5,6}, {7,8,9} }; // 3x3

// 存取
matrix[1, 2] = 42; // 第 1 列、第 2 行

// 迭代
for (int i = 0; i < matrix.GetLength(0); i++) {
    for (int j = 0; j < matrix.GetLength(1); j++) {
        Console.Write($"{matrix[i,j]} ");
    }
    Console.WriteLine();
}

// 屬性
matrix.Rank;        // 2 (維度數)
matrix.Length;      // 12 (總元素數)
matrix.GetLength(0); // 3 (第 0 維大小)

交錯陣列

陣列的陣列,每列可不同長度,記憶體不連續:

// 宣告: 3 列,每列長度不同
int[][] jagged = new int[3][];
jagged[0] = new int[] {1, 2};
jagged[1] = new int[] {3, 4, 5, 6};
jagged[2] = new int[] {7};

// 初始化簡寫
int[][] jagged2 = {
    new[] {1, 2},
    new[] {3, 4, 5},
    new[] {6}
};

// 存取
jagged[1][2] = 99; // 第 1 列、第 2 元素

// 迭代
foreach (var row in jagged) {
    foreach (var val in row) Console.Write($"{val} ");
    Console.WriteLine();
}

選擇指南:矩形陣列適合矩陣運算、影像處理;交錯陣列適合不規則資料(如稀疏矩陣、不定長序列)。

Array 類別核心靜態方法

方法說明
Sort(Array)原地排序 (QuickSort/IntroSort),支援自訂 IComparer
BinarySearch二分搜尋,陣列必須已排序
Reverse原地反轉
Copy高效複製區段,支援跨型別 (需相容)
ConstrainedCopy不可部分完成複製 (全成功或全失敗)
Resize調整大小 (建立新陣列複製)
Clear將區段設為預設值
Find/FindAll/FindIndex搜尋符合條件元素
ConvertAll型別轉換投影
ForEach對每個元素執行 Action
AsReadOnly建立唯讀包裝

陣列與泛型介面

陣列隱含實作:

  • IList<T>:Count、this[int]、Add/Remove 擲出 NotSupportedException
  • IReadOnlyList<T>:唯讀存取
  • IEnumerable<T>:foreach、LINQ
int[] arr = {3,1,4,1,5};
IList list = arr;
list.Count;        // 5
list[2];           // 4
// list.Add(9);    // 執行期例外

// LINQ 直接使用
var evens = arr.Where(x => x % 2 == 0).ToArray(); // {4}

Span<T>:零配置切片

.NET Core 2.1+ Span<T> 是 ref struct,提供陣列區段的安全、零配置、堆疊專用視圖:

int[] data = {1,2,3,4,5,6,7,8,9,10};
Span slice = data.AsSpan(2, 4); // 索引 2 起長度 4: {3,4,5,6}

// 修改切片會影響原陣列
slice[0] = 99; // data[2] 變為 99

// 切片操作
var first3 = slice.Slice(0, 3); // {99,4,5}
var rest = slice[3..];          // Range 索引 (C# 8+)

// 避免子陣列配置
void Process(Span buffer) { /* ... */ }
Process(data.AsSpan(100, 50)); // 零配置

限制:Span<T> 不可作為類別欄位、陣列元素、封箱、跨 await/yield。長壽命切片用 Memory<T>。

陣列段

ArraySegment<T> 是結構體,包裝陣列+偏移+長度,適用舊版 API:

var segment = new ArraySegment(data, 2, 4);
foreach (var x in segment) Console.WriteLine(x);

最佳實踐

  • 優先用 List<T>:動態大小、豐富 API、效能差異微小。
  • 固定大小、高效能、互通性:用陣列。
  • 避免多維陣列效能陷阱:matrix[i,j] 有邊界檢查開銷;熱路徑考慮交錯陣列或一維陣列手動索引 i * width + j。
  • 大量數值運算:考慮 System.Numerics.Vector<T> SIMD、ArrayPool<T> 重用緩衝區。
  • 公開 API 回傳:回傳 IReadOnlyList<T> 或 ReadOnlySpan<T>,避免呼叫端修改內部陣列。
  • 初始化大陣列:ArrayPool<T>.Shared.Rent(size) 避免 LOH 配置/GC。

常見問題 FAQ

Q: 陣列大小能改變嗎?

A: 不能。Array.Resize 是建立新陣列並複製,原參考不變。需動態大小請用 List<T>。

Q: 多維陣列 vs 交錯陣列效能?

A: 交錯陣列通常較快:單一索引 arr[i][j] 編譯為兩次簡單索引;多維陣列 arr[i,j] 有方法呼叫與邊界檢查開銷。但多維陣列記憶體連續,大型矩陣快取表現較好。

Q: 如何安全地將陣列傳給不信任程式碼?

A: 回傳 array.ToArray() 複本、或 array.AsReadOnly()、或 ReadOnlySpan<T>。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved