19 Feb 2015 by K Bonneau

Note: This feature though present in the older previews of C# 6 has now been removed. The article below has enough reasons against its use.

In C# 6, you can now have default parameterless constructors for structs. Following is an example:





default(S) and new S() are totally different things

Problems with initializing all fields with default constructor

For a struct MyStruct, if you dont have a parameterless constructor, default(MyStruct) and new MyStruct() would give you the same result. However if you have a parameterless constructor, new MyStruct() would return the result after running the constructor, however default(MyStruct) runs the inbuilt constructor which zeroes in all members. So both results may not be the same.All construtors for a struct should initialize all its fields. If any of the fields is not initialized, the compiler will give you an error. If you have too many fields, it can be a pain to set all the values. And with auto-properties there you cannot assign a value to the underlying field as it is hidden, and you cannot use the setter, because you cannot invoke function member until all fields have bee assigned.

For Constructors with parameters this was easy. You could call the default constructor from the constructor with parameters, which would initialize all the fields, and the compiler would stop complaining.

MyStruct(int x): this() { this.x = x; }

But you may not be able to do this with parameterless constructors.

MyStruct(): this() //Error.. you are calling yourself? { this.x = -1; }

The workaround is calling default(MyStruct) and assign it to "this" (yes you can do that)

Default constructors on structs must be public

You cannot have private, protected or internal default constructors for structs. Remember there are logically two default constructors one that has been explicitly written and another inbuilt which is equivalent to default(T). If we make the constructor internal, the constructor would get used within the library, but outside the library it is not available. However default(T) is still "publicly" available and hence that would get used. It is bad to have different behavior based on where the code is called. So the c# team decided on adding this restriction.

Related: