2

In C#, the following is valid syntax, and this makes sense:

string[] v = {"a","b"};

But now consider this. Suppose we define

void method(string[] p) {...};

Then the following is not valid:

method({"a","b"});

which is inconsistent with the above.

Are there technical reasons that preclude the method call here from being valid syntax? That is, is there some ambiguity in interpretation of the syntax? Or is there some issue with memory management or persistence that makes it impossible to implement?

Edit: Eric Lippert's answer below is interesting - but it answers the "why" of design, which I wasn't actually asking (and indeed this question was originally closed because it appeared as though I was asking for his sort of answer).

L.B's answer may indeed not be the original "reason why" this syntax was no allowed (as per Eric L. comments). However, L.B's answer, as of now, is certainly a correct technical reason why such syntax could not be allowed, which is actually the question I was asking, so I choose to select L.B's answer as correct (though honestly it was a hard choice...).

10
  • 3
    This is valid: method(new[] {"a","b"}); Commented Sep 14, 2016 at 19:58
  • 4
    Suppose you have another method void method(KeyValuePair<string,string> p) {} Which one is invoked? (See initialization of a dictionary) Commented Sep 14, 2016 at 19:58
  • 3
    It isn't inconsistent. It is based on type inference. However, there is a reasonable limit to how far C# takes type inference before strong typing begins to break down and L.B just gave a great example of where that can happen. Commented Sep 14, 2016 at 20:00
  • 1
    Yeah, type inference is only syntactic sugar provided for convenience only in unambiguous cases. Commented Sep 14, 2016 at 20:01
  • @L.B: These were the answers I was looking for. L.B.'s answer is certainly sufficient to rule out allowing the syntax, (and it's not opinion-based, but technical and factual). Thanks. (So L.B., enter your comment as an answer and I'll accept it.) Commented Sep 14, 2016 at 20:17

2 Answers 2

7

Short answer: it's an oddity of the grammar. I've always considered this to be a "wart". There are a number of ways you can look at this thing and say it is weird. It is weird that it is one of the few situations where:

T x = y;

and

T x; x = y;

are different. Or, another way to look at it is that it is weird that a local variable initializer is a context in which something that is not an expression can appear.

Or another way to look at it is it is really weird that this is the only situation in which a new array is created but "new" does not appear anywhere.

Or another way to look at it is it is really weird that arrays can be initialized like this, but no other collection constructs can. It makes arrays seem particularly special and important, even though they are often not the right tool for the job.

I think if we had to do it all over again, probably initializers would require new[] to their left.

Are there technical reasons that preclude the method call here from being valid syntax? That is, is there some ambiguity in interpretation of the syntax?

Not really. Don't read too much into this oddity. My advice is to avoid the syntax entirely; stick with proper collection initializers or array initializers. They have almost exactly the same syntax, but are legal anywhere an expression is legal.

Regarding the other answer, of L.B.: Though this answer does plausibly point out that there is a design issue here, it ignores the historical perspective. The feature being critiqued was created in C# 1.0, years before generic type inference (C# 2.0) or other braced collection initializers (C# 3.0) were added. So one cannot make a justification for the design choices of a 1.0 feature on the basis of some conflict with features that came years later. The C# design team tries to be forward looking, but they were not that forward looking!

Sign up to request clarification or add additional context in comments.

6 Comments

"... it is really weird that arrays can be initialized like this, but no other collection constructs can". Isn't somehow similar to this type of initialization: new Office { Employees = { "Denise", "John" } }; where Employees is a list of strings that is created in the Office constructor? How is this type of initialization called?
@LucaCremonesi: That's a collection initializer. My point is that you can't say List<int> myList = { 1, 2, 3, }; but you can say int[] myArray = {1, 2, 3};, and so arrays are special. Why should arrays be special but lists not be special? Particularly since, as you correctly note, you can do that in the context of an object or collection initializer.
Thanks for this. Its a shame that one can no longer ask the type of question to which your answer truly applies, because they are "opinion" questions. The "opinions" of people with your experience are rather valuable, and its a shame that SO no longer recognizes this.
@DavidI.McIntosh: I am well known around here for pushing back on vague "why" questions; that said, I think your question in its present form is clear. For more thoughts on this see meta.stackoverflow.com/questions/323334/… and meta.stackoverflow.com/questions/293815/…
Interesting reading. Makes me feel better about this question and its evolution...
|
3

Suppose you have another method

void method(KeyValuePair<string,string> p) {}

calling it like method({"a","b"}); would result in ambiguity..

Remember {"a","b"} may also be KeyValuePair<> as here

var dict = new Dictionary<string, string>() { { "a", "b" } };

1 Comment

This is incorrect. The initialization syntax for Dictionary<K,V> corresponds to the parameters of its Add() method and works for any collection type. This is an error: KeyValuePair<int,int> x = {0,0};

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.