An array-creation-expression is used to create a new instance of an
array-type.
array-creation-expression:
new non-array-type [ expression-list ] rank-specifiersopt
array-initializeropt
new array-type array-initializer
An array creation expression of the first form allocates an array instance
of the type that results from
deleting each of the individual expressions from the expression list.
[Example: For example, the array
creation expression new int[10,20] produces an array instance of type
int[,], and the array creation
expression new int[10][,] produces an array of type int[][,]. end example]
Each expression in the
expression list must be of type int, uint, long, or ulong, or of a type
that can be implicitly converted to
one or more of these types. The value of each expression determines the
length of the corresponding
dimension in the newly allocated array instance. Since the length of an
array dimension must be
C# LANGUAGE SPECIFICATION
148
nonnegative, it is a compile-time error to have a constant expression with
a negative value, in the expression
list.
Except in an unsafe context (?5.1), the layout of arrays is unspecified.
If an array creation expression of the first form includes an array
initializer, each expression in the
expression list must be a constant and the rank and dimension lengths
specified by the expression list must
match those of the array initializer.
In an array creation expression of the second form, the rank of the
specified array type must match that of
the array initializer. The individual dimension lengths are inferred from
the number of elements in each of
the corresponding nesting levels of the array initializer. Thus, the
expression
new int[,] {{0, 1}, {2, 3}, {4, 5}}
exactly corresponds to
new int[3, 2] {{0, 1}, {2, 3}, {4, 5}}
Array initializers are described further in ?9.6.
The result of evaluating an array creation expression is classified as a
value, namely a reference to the newly
allocated array instance. The run-time processing of an array creation
expression consists of the following
steps:
?The dimension length expressions of the expression-list are evaluated in
order, from left to right.
Following evaluation of each expression, an implicit conversion (?3.1) to
one of the following types is
performed: int, uint, long, ulong. The first type in this list for which an
implicit conversion exists is
chosen. If evaluation of an expression or the subsequent implicit
conversion causes an exception, then
no further expressions are evaluated and no further steps are executed.
?The computed values for the dimension lengths are validated, as follows:
If one or more of the values
are less than zero, a System.OverflowException is thrown and no further
steps are executed.
?An array instance with the given dimension lengths is allocated. If there
is not enough memory available
to allocate the new instance, a System.OutOfMemoryException is thrown and
no further steps are
executed.
?All elements of the new array instance are initialized to their default
values (?2.2).
?If the array creation expression contains an array initializer, then each
expression in the array initializer
is evaluated and assigned to its corresponding array element. The
evaluations and assignments are
performed in the order the expressions are written in the array
initializer?in other words, elements are
initialized in increasing index order, with the rightmost dimension
increasing first. If evaluation of a
given expression or the subsequent assignment to the corresponding array
element causes an exception,
then no further elements are initialized (and the remaining elements will
thus have their default values).
An array creation expression permits instantiation of an array with
elements of an array type, but the
elements of such an array must be manually initialized. [Example: For
example, the statement
int[][] a = new int[100][];
creates a single-dimensional array with 100 elements of type int[]. The
initial value of each element is
null. end example] It is not possible for the same array creation
expression to also instantiate the subarrays,
and the statement
int[][] a = new int[100][5]; // Error
results in a compile-time error. Instantiation of the sub-arrays must
instead be performed manually, as in
int[][] a = new int[100][];
for (int i = 0; i < 100; i++) a[i] = new int[5];
When an array of arrays has a ?rectangular? shape, that is when the
sub-arrays are all of the same length, it is
more efficient to use a multi-dimensional array. In the example above,
instantiation of the array of arrays
creates 101 objects?one outer array and 100 sub-arrays. In contrast,
Chapter 14 Expressions
149
int[,] = new int[100, 5];
creates only a single object, a two-dimensional array, and accomplishes the
allocation in a single statement.