Structures are peculiar creatures in C#. One of more interesting peculiarities comes in combination with auto-implemented properties.
Lets begin with following struct:
public struct Test {
public Test(int a) {
this.A = 1;
}
public int A;
}
It is something that works, but having variable A directly exposed is not something that looks too good. Auto-implemented properties come to rescue:
public struct Test {
public Test(int a) {
this.A = 1;
}
public int A { get; set; }
}
This looks much better from design point of view. However, it also does not compile. It will greet us with: “Backing field for automatically implemented property ‘Test.A’ must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.”
Solution is quite simple, just call default constructor (as suggested in error message) and everything is fine:
public struct Test {
public Test(int a)
this(): {
this.A = 1;
}
public int A { get; set; }
}
Unfortunately, you gain something, you lose something. Our original structure stops us when we forget to initialize field and I think of this as great feature. It ensures that we cannot forget a field.
Solution with auto-implemented properties has no such assurance. Since we need to call default constructor at one point or another, we will end-up with all fields initialized by struct itself. There will be no further checks whether fields are set or not.
While code did get nicer, our refactoring just got harder.