Why can’t I define a default constructor for a struct in .NET?

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?

  • If not, we end up with 1000 invalid rationals
  • If it does, then we’ve potentially wasted a load of work if we’re about to fill in the array with real values.

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.

Leave a Comment