tags:

views:

654

answers:

7
+4  Q: 

C# Using new[]

I have a question about using new[].

Imagine this:

Object.SomeProperty = new[] {"string1", "string2"};

Where SomeProperty expects an array of strings.

I know this code snippet will work. But i want to know what it does under the hood. Does new[] makes an instance of the class object and in SomeProperty it converts it automatically to a string object?

Thanks

+12  A: 

This is just syntactical sugar. The compiler will infer the type actually necessary here and create code that is equivalent to the explicit construct:

Object.SomeProperty = new string[] {"string1", "string2"};

There's no such thing as new[] that gets executed at runtime.

Konrad Rudolph
+2  A: 

The compiler replaces:

Object.SomeProperty = new[] {"string1", "string2"};

with:

Object.SomeProperty = new string[] {"string1", "string2"};
Darin Dimitrov
Object.SomeProperty = {"string1", "string2"};Not in any C# compiler I have ever seen! You can only do that during initialization.
leppie
initialization, being variable initialization. eg. string[] foo = {"bar","baz"};
leppie
@leppie, aboslutely right. I stand corrected
Darin Dimitrov
+3  A: 

It is roughly translated to:

string[] $temp = new string[2];
$temp[0] = "string1";
$temp[1] = "string2";
Object.SomeProperty = $temp;

Interestingly, var x = new[] { "string1", "string2" }; works as well, it can infer x to be a string[], but var x = { "string1", "string2" }; fails.

Simon Buchan
That's because an array is a reference type that must be allocated with new. Nothing is going to syntactically sugar that away.
Dave Van den Eynde
Yes, but when given a type, the non `new[]` syntax news up the type, passing the IEnumerable<T>, so when it only has var, why couldn't it last ditch default to T[]?
Simon Buchan
A: 

Thnx for the answers.

So the compiler sees that SomeProperty needs a string array. And because there was passed a object of type object, the compiler translate it to new string["string1","string2"] ?

Martijn
No, the compiler infers the type of the array with the values you give into braces. Since the values are string, it infers the array to be a string[]. The type of SomeProperty isn't used.
Luc Touraille
Ninja'd! With identical, more succinct statements! Damn you stackoverflow.com, where's my 'New comments that have made your work irrelevant and annoying have been posted!' notification?
Simon Buchan
You're still free to delete your comment.
Dave Van den Eynde
I worry you are confusing array type covariance with type inference here! The fact that a string (like everything else) derives from object doesn't even come into this here, as my esteemed so colleagues so wisely point out!!
kronoz
@Dave: fine, but I'll leave the other to confuse people.
Simon Buchan
A: 

I do hope from your response you're not getting confused between type substitution and type inference here! I'm assuming the type of Object.SomeProperty is string[], though due to array covariance it could be object[] (note this would not be a good thing - check out Eric Lippert's post on this subject!).

The compiler performs type inference using a heuristic - it determines that "string1" and "string2" are of type string, and therefore it effectively replaces your code with:-

Object.SomeProperty = new string[] {"string1", "string2"};

It really is as simple as that! It's all done at compile time, nothing at run time.

kronoz
+11  A: 

Okay, there's still a little bit of confusion here.

The inference that's going on has nothing to with the type of Object.SomeProperty, but everything to do with the types of the expressions in the array initializer. In other words, you could do:

object o = new[] { "string1", "string2" };

and o would still be a reference to a string array.

Basically, the compiler looks at an expression like this:

new[] { A, B, C, D, ... }

(where A, B, C, D etc are expressions) and tries to work out the correct array type to use. It only considers the types of A, B, C and D (etc) as the array element type. Taking this set of candidate types, it tries to find one which all the others can be implicitly converted to. If there's not exactly one such type then the compiler will complain.

So for example:

new[] { new Form(), new MemoryStream() }

will not compile - neither MemoryStream nor Form is convertible to the other. However:

new[] { GetSomeIDisposable(), new MemoryStream() }

will be treated as an IDisposable[] because there's an implicit conversion from MemoryStream to IDisposable. Likewise:

new[] { 0, 1, 3.5 } // double[]
new[] { 1, 3, 100L } // long[]
Jon Skeet
A: 

Thnx i get i now :)

Martijn