views:

98

answers:

7

I am trying to compile following code in C#

String[] words = { "Hello", "Worlds" };
words = {"Foo", "Bar"};

and am getting compilation errors like

Error 1 Invalid expression term '{'
Error 2 ; expected
Error 3 Invalid expression term ','

On the other hand if i try

String[] words = { "Hello", "Worlds" };
words = new String[] {"Foo", "Bar"};

It compiles fine. As per MSDN

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

is simply shorthand for an equivalent array creation expression:

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

Now my question is that why the first code sample doesn't compile?

Thanks

+7  A: 

Correct, the short initializer syntax is only allowed in a declaration. Not in a normal statement.

String[] words = new string[]{ "Hello", "Worlds" }; // full form
String[] words = { "Hello", "Worlds" };  // short hand, special rule
words = {"Foo", "Bar"};                  // not allowed
words = new String[] {"Foo", "Bar"};     // allowed, full form again

The short hand notation is only allowed when it used as (rhs) part of a declaration.

Henk Holterman
+1  A: 

According to the docs you linked to, array initializers are only valid by themselves in field or variable declarations - for variable assignments, you have to specify new[] beforehand:

In an array creation expression (the general case), the array type immediately precedes the initializer. In a field or variable declaration, the array type is the type of the field or variable being declared.

thecoop
A: 

As per the same MSDN page, this syntax is specific to array variable initialization; it's not a general-purpose array syntax.

However, this is close:

String[] words = { "Hello", "Worlds" };
// words = {"Foo", "Bar"};
words = new[] {"Foo", "Bar"};
Tim Robinson
A: 

The compiler error you are refering to is caused by invaild syntax.

// variable declaration so constructor may be assumed
String[] words = { "Hello", "Worlds" }; 

// attempted variable assignment using invalid syntax
words = {"Foo", "Bar"}; 

// explicit constructor
words = new String[] {"Foo", "Bar"};

// as a note this would also work.  Here the why of the array is assumed.
words = new [] {"Foo", "Bar"};
Matthew Whited
+2  A: 

C# spec 12.6 Array initializers

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};

String[] words = { "Hello", "Worlds" };

is a declaration but

words = {"Foo", "Bar"};

is not.

desco
Need to pay more attention when reading docs. Thanks
Babar
A: 

Array initializers used as part of variable declarations are special, basically. (I can't look up the spec reference right now, but I can do so later on.) Outside a variable declaration, the compiler doesn't really take much notice of the fact that there's an assignment - the expression on the right hand side has to stand on its own two feet, as it were.1

In C# 3 you can use a slightly abbreviated form:

words = new[] {"Foo", "Bar"};

This will infer the type of the array (at compile-time) from the elements within it... and assuming it's compatible with the target variable, the assignment will work. This syntax works in a more general context - you can use it to pass arrays as method arguments, for example.

There's no way of using the "completely abbreviated" form outside variable declarations though.


1 Admittedly there are some expressions which don't have a type, such as lambda expressions.

Jon Skeet
A: 

During initialization, you are explicitly declaring the type of the array, which makes this shorthand clear and unambiguous. However, later on in the code, a little ambiguity starts to creep in. You could, in theory, be trying to set up an array of objects, for example. Sure, you probably want it to be an array of strings, but for the sake of avoiding logical errors, the compiler doesn't want to assume something like that unless it's extremely clear what you're trying to do.

Justin Morgan