The version that compiles uses an array initializer to initialize list1. The C# language spec, §1.110 (“Array initializers”) states:
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};
So it is obvious that this should compile.
The second version uses an explicit array creation expression, where you instruct the compiler specifically what type of array to create. §1.51.10.4 (“Array creation expressions”) states:
An array creation expression of the third form is referred to as an
implicitly typed array creation expression. It is similar to the
second form, except that the element type of the array is not
explicitly given, but determined as the best common type (§1.50.2.14)
of the set of expressions in the array initializer.
Therefore, the second version is equivalent to
object[] list2 = new int[] { 0, 1 };
So the question now effectively becomes “why can I not assign an int[] to an object[]“, just as you mention at the end of the question. And the answer is also simple, given in §1.109 (“Array covariance”):
Array covariance specifically does not extend to arrays of
value-types. For example, no conversion exists that permits anint[]
to be treated as anobject[].