陣列Arrays

陣列是資料結構,其中包含數個透過計算索引存取的變數。An array is a data structure that contains a number of variables which are accessed through computed indices. 陣列,也稱為陣列的項目中包含的變數都相同的型別,以及這個型別稱為陣列的項目類型。The variables contained in an array, also called the elements of the array, are all of the same type, and this type is called the element type of the array.

陣列的陣序規範用來決定每個陣列項目相關聯的索引鍵的數目。An array has a rank which determines the number of indices associated with each array element. 陣列的陣序規範也稱為陣列的維度。The rank of an array is also referred to as the dimensions of the array. 陣列陣序規範的其中一個稱為維陣列An array with a rank of one is called a single-dimensional array. 陣列陣序規範大於其中一個稱為多維陣列An array with a rank greater than one is called a multi-dimensional array. 特定大小的多維度陣列通常稱為二維陣列,三維陣列,以及等等。Specific sized multi-dimensional arrays are often referred to as two-dimensional arrays, three-dimensional arrays, and so on.

陣列的每個維度具有相關聯的長度,也就是大於或等於零的整數。Each dimension of an array has an associated length which is an integral number greater than or equal to zero. 維度長度不是陣列型別的一部分,但而不是建立陣列型別的執行個體建立在執行階段時。The dimension lengths are not part of the type of the array, but rather are established when an instance of the array type is created at run-time. 維度的長度將決定該維度的索引的有效範圍:維度的長度N,索引的範圍可以從0N - 1(含)。The length of a dimension determines the valid range of indices for that dimension: For a dimension of length N, indices can range from 0 to N - 1 inclusive. 陣列中的元素總數是產品之陣列中每個維度的長度。The total number of elements in an array is the product of the lengths of each dimension in the array. 如果一或多個維度的陣列擁有長度為零,陣列即為空白。If one or more of the dimensions of an array have a length of zero, the array is said to be empty.

陣列的元素型別可以是任一型別,包括陣列型別。The element type of an array can be any type, including an array type.

陣列型別Array types

陣列類型以寫入non_array_type後面接著一或多個rank_specifiers:An array type is written as a non_array_type followed by one or more rank_specifiers:

array_type
    : non_array_type rank_specifier+
    ;

non_array_type
    : type
    ;

rank_specifier
    : '[' dim_separator* ']'
    ;

dim_separator
    : ','
    ;

A non_array_type可以是任何型別也就是本身並非array_typeA non_array_type is any type that is not itself an array_type.

陣列類型的陣序規範根據最左邊rank_specifierarray_type:A rank_specifier表示陣列的陣列,陣序規範的數目加一,「,"的語彙基元rank_specifierThe rank of an array type is given by the leftmost rank_specifier in the array_type: A rank_specifier indicates that the array is an array with a rank of one plus the number of "," tokens in the rank_specifier.

陣列類型的項目類型是類型所產生的刪除最左邊rank_specifier:The element type of an array type is the type that results from deleting the leftmost rank_specifier:

  • 陣列類型的表單T[R]是陣列陣序規範R和非陣列元素型別TAn array type of the form T[R] is an array with rank R and a non-array element type T.
  • 陣列類型的表單T[R][R1]...[Rn]是陣列陣序規範R和 項目類型T[R1]...[Rn]An array type of the form T[R][R1]...[Rn] is an array with rank R and an element type T[R1]...[Rn].

實際上rank_specifiers 會從左向右讀取前的最後一個非陣列項目的類型。In effect, the rank_specifiers are read from left to right before the final non-array element type. 型別int[][,,][,]是一維陣列的二維陣列的三維陣列intThe type int[][,,][,] is a single-dimensional array of three-dimensional arrays of two-dimensional arrays of int.

在執行階段陣列型別的值可以是null或該陣列型別的執行個體的參考。At run-time, a value of an array type can be null or a reference to an instance of that array type.

System.Array 型別The System.Array type

型別System.Array是所有陣列類型的抽象基底類型。The type System.Array is the abstract base type of all array types. 隱含參考轉換 (隱含參考轉換) 存在從任何陣列型別System.Array,並明確參考轉換 (明確參考轉換) 是否存在從System.Array任何陣列類型。An implicit reference conversion (Implicit reference conversions) exists from any array type to System.Array, and an explicit reference conversion (Explicit reference conversions) exists from System.Array to any array type. 請注意,System.Array本身並不會array_typeNote that System.Array is not itself an array_type. 而是class_type所有array_types 衍生。Rather, it is a class_type from which all array_types are derived.

在執行階段,類型的值System.Array可以是null或任何陣列類型的執行個體的參考。At run-time, a value of type System.Array can be null or a reference to an instance of any array type.

陣列和泛型 IList 介面Arrays and the generic IList interface

一維陣列T[]實作介面System.Collections.Generic.IList<T>(IList<T>簡稱) 和其基底介面。A one-dimensional array T[] implements the interface System.Collections.Generic.IList<T> (IList<T> for short) and its base interfaces. 因此,沒有從的隱含轉換T[]IList<T>和其基底介面。Accordingly, there is an implicit conversion from T[] to IList<T> and its base interfaces. 此外,如果沒有從隱含參考轉換STS[]實作IList<T>,而且沒有從隱含參考轉換S[]IList<T>和其基底介面 (隱含參考轉換)。In addition, if there is an implicit reference conversion from S to T then S[] implements IList<T> and there is an implicit reference conversion from S[] to IList<T> and its base interfaces (Implicit reference conversions). 如果沒有明確參考轉換從ST的明確參考轉換就S[]IList<T>及其基底介面 (明確參考轉換).If there is an explicit reference conversion from S to T then there is an explicit reference conversion from S[] to IList<T> and its base interfaces (Explicit reference conversions). 例如: For example:

using System.Collections.Generic;

class Test
{
    static void Main() {
        string[] sa = new string[5];
        object[] oa1 = new object[5];
        object[] oa2 = sa;

        IList<string> lst1 = sa;                    // Ok
        IList<string> lst2 = oa1;                   // Error, cast needed
        IList<object> lst3 = sa;                    // Ok
        IList<object> lst4 = oa1;                   // Ok

        IList<string> lst5 = (IList<string>)oa1;    // Exception
        IList<string> lst6 = (IList<string>)oa2;    // Ok
    }
}

工作分派lst2 = oa1從轉換後就會產生編譯時期錯誤object[]IList<string>是明確的轉換,不隱含。The assignment lst2 = oa1 generates a compile-time error since the conversion from object[] to IList<string> is an explicit conversion, not implicit. 轉型(IList<string>)oa1將會在之後的執行時期擲回的例外狀況oa1參考object[]而非string[]The cast (IList<string>)oa1 will cause an exception to be thrown at run-time since oa1 references an object[] and not a string[]. 不過轉型(IList<string>)oa2不會因為擲回例外狀況oa2參考string[]However the cast (IList<string>)oa2 will not cause an exception to be thrown since oa2 references a string[].

每當沒有隱含或明確參考轉換S[]IList<T>,也是從明確參考轉換IList<T>和其基底介面S[](明確參考轉換)。Whenever there is an implicit or explicit reference conversion from S[] to IList<T>, there is also an explicit reference conversion from IList<T> and its base interfaces to S[] (Explicit reference conversions).

當陣列型別S[]實作IList<T>,某些實作介面的成員可能會擲回例外狀況。When an array type S[] implements IList<T>, some of the members of the implemented interface may throw exceptions. 精確的行為的介面的實作已超出此規格的範圍。The precise behavior of the implementation of the interface is beyond the scope of this specification.

建立陣列Array creation

藉由建立陣列執行個體array_creation_expressions (陣列建立運算式) 或欄位或區域變數宣告包含array_initializer(陣列初始設定式)。Array instances are created by array_creation_expressions (Array creation expressions) or by field or local variable declarations that include an array_initializer (Array initializers).

建立陣列執行個體時,順位和每個維度的長度所建立,然後保持不變執行個體的整個存留期間。When an array instance is created, the rank and length of each dimension are established and then remain constant for the entire lifetime of the instance. 換句話說,就無法變更現有的陣列執行個體的陣序,也不是可調整大小及其維度。In other words, it is not possible to change the rank of an existing array instance, nor is it possible to resize its dimensions.

陣列執行個體一律會是陣列型別。An array instance is always of an array type. System.Array型別是抽象類型無法具現化。The System.Array type is an abstract type that cannot be instantiated.

所建立的陣列的元素array_creation_expressions 一律會初始化為其預設值 (預設值)。Elements of arrays created by array_creation_expressions are always initialized to their default value (Default values).

陣列元素存取Array element access

陣列項目用來存取element_access運算式 (陣列存取) 的形式A[I1, I2, ..., In],其中A是陣列型別和每個運算式Ix是類型的運算式intuintlongulong,或可以隱含地轉換為一或多個這些型別。Array elements are accessed using element_access expressions (Array access) of the form A[I1, I2, ..., In], where A is an expression of an array type and each Ix is an expression of type int, uint, long, ulong, or can be implicitly converted to one or more of these types. 陣列元素存取的結果是一個變數,也就是選取索引的陣列元素。The result of an array element access is a variable, namely the array element selected by the indices.

陣列的項目可以使用列舉foreach陳述式 (foreach 陳述式)。The elements of an array can be enumerated using a foreach statement (The foreach statement).

陣列成員Array members

每個陣列型別會繼承由宣告成員System.Array型別。Every array type inherits the members declared by the System.Array type.

陣列共變數Array covariance

任何兩個reference_typesAB,如果隱含參考轉換 (隱含參考轉換) 或明確參考轉換 (明確參考轉換) 從AB,然後從陣列類型也存在相同的參考轉換A[R]為陣列型別B[R],其中R的話給定rank_specifier (但相同陣列型別)。For any two reference_types A and B, if an implicit reference conversion (Implicit reference conversions) or explicit reference conversion (Explicit reference conversions) exists from A to B, then the same reference conversion also exists from the array type A[R] to the array type B[R], where R is any given rank_specifier (but the same for both array types). 此關聯性就所謂陣列共變數This relationship is known as array covariance. 陣列共變數特別表示陣列型別的值A[R]實際上可能是陣列型別的執行個體的參考B[R],如果隱含參考轉換存在BAArray covariance in particular means that a value of an array type A[R] may actually be a reference to an instance of an array type B[R], provided an implicit reference conversion exists from B to A.

陣列共變數,因為指派給參考型別陣列的項目會包含執行階段檢查可確保指派給陣列元素的值實際上是允許的型別 (簡單指派)。Because of array covariance, assignments to elements of reference type arrays include a run-time check which ensures that the value being assigned to the array element is actually of a permitted type (Simple assignment). 例如: For example:

class Test
{
    static void Fill(object[] array, int index, int count, object value) {
        for (int i = index; i < index + count; i++) array[i] = value;
    }

    static void Main() {
        string[] strings = new string[100];
        Fill(strings, 0, 100, "Undefined");
        Fill(strings, 0, 10, null);
        Fill(strings, 90, 10, 0);
    }
}

指派給array[i]Fill方法會隱含地包含執行階段檢查可確保所參考的物件valuenull實際的項目類型相容的執行個體或array.The assignment to array[i] in the Fill method implicitly includes a run-time check which ensures that the object referenced by value is either null or an instance that is compatible with the actual element type of array. Main的前兩個引動過程Fill成功,但第三個引動過程會導致System.ArrayTypeMismatchException擲回時執行的第一個指派array[i]In Main, the first two invocations of Fill succeed, but the third invocation causes a System.ArrayTypeMismatchException to be thrown upon executing the first assignment to array[i]. 因為發生例外狀況 boxedint無法儲存在string陣列。The exception occurs because a boxed int cannot be stored in a string array.

陣列共變數特別不會延伸到的陣列value_types。Array covariance specifically does not extend to arrays of value_types. 例如,沒有任何轉換存在該允許int[]視為object[]For example, no conversion exists that permits an int[] to be treated as an object[].

陣列初始設定式Array initializers

陣列初始設定式可能會在欄位宣告中指定 (欄位),本機變數宣告 (區域變數宣告),和陣列建立運算式 (陣列建立運算式):Array initializers may be specified in field declarations (Fields), local variable declarations (Local variable declarations), and array creation expressions (Array creation expressions):

array_initializer
    : '{' variable_initializer_list? '}'
    | '{' variable_initializer_list ',' '}'
    ;

variable_initializer_list
    : variable_initializer (',' variable_initializer)*
    ;

variable_initializer
    : expression
    | array_initializer
    ;

陣列初始設定式所組成的變數初始設定式,用括住的一連串 「{"和"}「 語彙基元和分隔 」,"語彙基元。An array initializer consists of a sequence of variable initializers, enclosed by "{" and "}" tokens and separated by "," tokens. 每個變數的初始設定式是一種運算式或在多維度陣列,巢狀的陣列初始設定式的情況下。Each variable initializer is an expression or, in the case of a multi-dimensional array, a nested array initializer.

其中的陣列初始設定式會使用內容決定要初始化之陣列的類型。The context in which an array initializer is used determines the type of the array being initialized. 陣列建立運算式,在陣列型別,立即之前的初始設定式,或從陣列初始設定式中的運算式推斷進行相關的設定。In an array creation expression, the array type immediately precedes the initializer, or is inferred from the expressions in the array initializer. 在欄位或變數宣告中,陣列型別是欄位或所宣告變數的類型。In a field or variable declaration, the array type is the type of the field or variable being declared. 陣列初始設定式中使用時的欄位或變數宣告,例如:When an array initializer is used in a field or variable declaration, such as:

int[] a = {0, 2, 4, 6, 8};

它是簡略的對等陣列建立運算式:it is simply shorthand for an equivalent array creation expression:

int[] a = new int[] {0, 2, 4, 6, 8};

一維陣列,陣列初始設定式必須包含一系列的指派相容於陣列的項目類型的運算式。For a single-dimensional array, the array initializer must consist of a sequence of expressions that are assignment compatible with the element type of the array. 運算式,初始化陣列元素,以遞增次序順序,從索引零處的項目。The expressions initialize array elements in increasing order, starting with the element at index zero. 陣列初始設定式中的運算式數目會決定所建立的陣列執行個體的長度。The number of expressions in the array initializer determines the length of the array instance being created. 例如,上述的陣列初始設定式會建立int[]長度為 5 的執行個體,然後初始化的執行個體,使用下列值:For example, the array initializer above creates an int[] instance of length 5 and then initializes the instance with the following values:

a[0] = 0; a[1] = 2; a[2] = 4; a[3] = 6; a[4] = 8;

多維陣列,陣列初始設定式必須有多個層級的巢狀陣列中的維度相同。For a multi-dimensional array, the array initializer must have as many levels of nesting as there are dimensions in the array. 最外層巢狀層級對應至最左邊的維度,最內層的巢狀層級對應於最右側的維度。The outermost nesting level corresponds to the leftmost dimension and the innermost nesting level corresponds to the rightmost dimension. 陣列的每個維度的長度取決於對應的巢狀層級的陣列初始設定式中的項目數。The length of each dimension of the array is determined by the number of elements at the corresponding nesting level in the array initializer. 每個巢狀的陣列初始設定式中,項目數目必須與其他陣列初始設定式在相同的層級相同。For each nested array initializer, the number of elements must be the same as the other array initializers at the same level. 範例:The example:

int[,] b = {{0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}};

建立二維陣列的長度為五個最左邊的維度與長度為兩個最右邊的維度:creates a two-dimensional array with a length of five for the leftmost dimension and a length of two for the rightmost dimension:

int[,] b = new int[5, 2];

然後初始化陣列執行個體和使用下列值:and then initializes the array instance with the following values:

b[0, 0] = 0; b[0, 1] = 1;
b[1, 0] = 2; b[1, 1] = 3;
b[2, 0] = 4; b[2, 1] = 5;
b[3, 0] = 6; b[3, 1] = 7;
b[4, 0] = 8; b[4, 1] = 9;

如果維度以外的最右邊長度為零,會假設後續的維度,也有長度為零。If a dimension other than the rightmost is given with length zero, the subsequent dimensions are assumed to also have length zero. 範例:The example:

int[,] c = {};

建立二維陣列的長度為零,最左邊和右邊的維度:creates a two-dimensional array with a length of zero for both the leftmost and the rightmost dimension:

int[,] c = new int[0, 0];

當陣列建立運算式包括明確的維度長度及陣列初始設定式時,長度必須是常數運算式,並在每個巢狀層級的項目數必須符合相對應維度的長度。When an array creation expression includes both explicit dimension lengths and an array initializer, the lengths must be constant expressions and the number of elements at each nesting level must match the corresponding dimension length. 以下是一些範例:Here are some examples:

int i = 3;
int[] x = new int[3] {0, 1, 2};        // OK
int[] y = new int[i] {0, 1, 2};        // Error, i not a constant
int[] z = new int[3] {0, 1, 2, 3};     // Error, length/initializer mismatch

這裡的初始設定式y導致編譯時期錯誤,因為維度長度運算式不是常數,與的初始設定式z導致編譯時期錯誤,因為長度和中的項目數不同意初始設定式。Here, the initializer for y results in a compile-time error because the dimension length expression is not a constant, and the initializer for z results in a compile-time error because the length and the number of elements in the initializer do not agree.