3

In C#, I can have a class such as:

class MyClass {
  public void DoStuff();
}

I can initialize this class like:

MyClass mc = new MyClass();

Or:

MyClass mc = new MyClass { };

If I don't need the parenthesis, and there are no properties to be set by an object initializer, why can't I do this?

MyClass mc = new MyClass;
CodingIntrigue
  • 75,930
  • 30
  • 170
  • 176
  • Maybe you'd like `Scala`. You can omit unnecessary parentheses on any constructor for function that takes no arguments. – KChaloux Sep 27 '13 at 13:59
  • 2
    @KChaloux C++ lets you do the same thing. – Sergey Kalinichenko Sep 27 '13 at 14:00
  • @sadblinkenlight Not for functions, it doesn't =P – KChaloux Sep 27 '13 at 14:03
  • 1
    @KChaloux You're right, C++ lets you do it only for constructors, because there's `new` keyword to tell the compiler what's going on. – Sergey Kalinichenko Sep 27 '13 at 14:07
  • It surprised me that you can omit the parenthesis if you have curly braces. I was happy when I could distinguish between code execution (you need () to call methods) and variable access (no () for fields or properties). The last syntax would be horrific in that regard. Yes, I write `new MyClass() { Number = 1 }` – DasKrümelmonster Sep 27 '13 at 14:15

5 Answers5

11

You cannot do MyClass mc = new MyClass because designers of the parser for the language decided not to allow you to do that. In fact, they were rather generous for allowing an empty pair of curly braces: I guess it was easier for them to take that route than explicitly asking for at least one expression.

There is nothing inherent in the structure of the new expression that you are proposing that would prohibit such syntax: modifying a parser to support the third alternative would not take much effort. However, doing so would create an inconsistency with calling non-constructor methods that have no arguments. Currently, omitting parentheses makes them method groups with specific semantic enabled in certain contexts. It would be hard to modify the parser to allow no-argument method calls without parentheses, because there would be no syntactic marker for it (note that when you call the constructor, the new keyword plays a role of such a marker).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 2
    +1, although this doesn't answer the implied question of "Why did they design the language that way?" But I can't think of an answer to that question myself... Best guess is that the parser needs to see parenetheses in order to recognize a reference to a method, to know to look through the v-Table, but then, they must have added code later to recognize the braces for the same thing. – Charles Bretana Sep 27 '13 at 14:00
  • @CharlesBretana I really do want to know the answer to that question, but felt it might open the question up to close votes – CodingIntrigue Sep 27 '13 at 14:02
  • To really get to know the _why_, you'll have to contact the C# language design team. The more interesting question is: why do **you** want to know? – CodeCaster Sep 27 '13 at 14:03
  • 1
    @CodeCaster Simple. The guys who designed C# are clever. This seems like redundant syntax, especially given the fact that C++ can do it. I am intrigued and wish to feed my OCD. – CodingIntrigue Sep 27 '13 at 14:05
  • @RGrapham, I think it is a very good question, but I don't know the answer. The `new` ought to be enough for a parser to determine that the next string token should be examined as the name of a type to be instantiated, so I think only the original language designers could answer (Eric Gunnersen, Anders Hejlsberg where are you?, Maybe even Kernigan/Ritchie ?) c – Charles Bretana Sep 27 '13 at 14:05
3

Because the syntax new MyClass { } is the new parameter-less constructor syntax, that's why you can omit the (). The constructor method public MyClass() is called by inference.

But, this syntax new MyClass is just bad because the compiler doesn't accept it as valid.

It's not that they couldn't do it, they can do just about anything with the compiler, but they aren't doing it.

Mike Perrenoud
  • 66,820
  • 29
  • 157
  • 232
3

Consider this:

public class MyClass {

    public int Value { get; private set; }

    public MyClass With(int i) {
        Value = i;
        return this;
    }
}

MyClass my = new MyClass().With(5);    // Old-school
MyClass my1 = new MyClass { }.With(6); // Kind of funky looking, but okay.
MyClass my2 = new MyClass.With(4);     // This looks just like a static method call except for the new
Keith Payne
  • 3,002
  • 16
  • 30
0

Because MyClass is the class name/type and MyClass() is the constructor; the one you need (want) to call is the constructor.

Michel Keijzers
  • 15,025
  • 28
  • 93
  • 119
0

This is because you are calling your default constructor for the object to be initialized. That's why, you use:

MyClass mc = new MyClass();

You can try, if there doesn't a default constructor (which takes zero number of arguments) exist, this line will give an error, saying something like, 'no default constructor exists'.

Zeeshan
  • 2,884
  • 3
  • 28
  • 47