In .NET, a value type (C# struct
) can\'t have a constructor with no parameters. According to this post this is mandated by the CLI specification. What happens i
Note: the answer below was written a long time prior to C# 6, which is planning to introduce the ability to declare parameterless constructors in structs - but they still won't be called in all situations (e.g. for array creation) (in the end this feature was not added to C# 6).
EDIT: I've edited the answer below due to Grauenwolf's insight into the CLR.
The CLR allows value types to have parameterless constructors, but C# doesn't. I believe this is because it would introduce an expectation that the constructor would be called when it wouldn't. For instance, consider this:
MyStruct[] foo = new MyStruct[1000];
The CLR is able to do this very efficiently just by allocating the appropriate memory and zeroing it all out. If it had to run the MyStruct constructor 1000 times, that would be a lot less efficient. (In fact, it doesn't - if you do have a parameterless constructor, it doesn't get run when you create an array, or when you have an uninitialized instance variable.)
The basic rule in C# is "the default value for any type can't rely on any initialization". Now they could have allowed parameterless constructors to be defined, but then not required that constructor to be executed in all cases - but that would have led to more confusion. (Or at least, so I believe the argument goes.)
EDIT: To use your example, what would you want to happen when someone did:
Rational[] fractions = new Rational[1000];
Should it run through your constructor 1000 times?
EDIT: (Answering a bit more of the question) The parameterless constructor isn't created by the compiler. Value types don't have to have constructors as far as the CLR is concerned - although it turns out it can if you write it in IL. When you write "new Guid()
" in C# that emits different IL to what you get if you call a normal constructor. See this SO question for a bit more on that aspect.
I suspect that there aren't any value types in the framework with parameterless constructors. No doubt NDepend could tell me if I asked it nicely enough... The fact that C# prohibits it is a big enough hint for me to think it's probably a bad idea.
A struct is a value type and a value type must have a default value as soon as it is declared.
MyClass m;
MyStruct m2;
If you declare two fields as above without instantiating either, then break the debugger, m
will be null but m2
will not. Given this, a parameterless constructor would make no sense, in fact all any constructor on a struct does is assign values, the thing itself already exists just by declaring it. Indeed m2 could quite happily be used in the above example and have its methods called, if any, and its fields and properties manipulated!
Shorter explanation:
In C++, struct and class were just two sides of the same coin. The only real difference is that one was public by default and the other was private.
In .NET, there is a much greater difference between a struct and a class. The main thing is that struct provides value-type semantics, while class provides reference-type semantics. When you start thinking about the implications of this change, other changes start to make more sense as well, including the constructor behavior you describe.
You can't define a default constructor because you are using C#.
Structs can have default constructors in .NET, though I don't know of any specific language that supports it.
You can make a static property that initializes and returns a default "rational" number:
public static Rational One => new Rational(0, 1);
And use it like:
var rat = Rational.One;
Just special-case it. If you see a numerator of 0 and a denominator of 0, pretend like it has the values you really want.