I'm toying with the idea of making primitive .NET value types more type-safe and more "self-documenting" by wrapping them in custom struct
s. However, I'm wondering if it's actually ever worth the effort in real-world software.
(That "effort" can be seen below: Having to apply the same code pattern again and again. We're declaring
struct
s and so cannot use inheritance to remove code repetition; and since the overloaded operators must be declaredstatic
, they have to be defined for each type separately.)
Take this (admittedly trivial) example:
struct Area
{
public static implicit operator Area(double x) { return new Area(x); }
public static implicit operator double(Area area) { return area.x; }
private Area(double x) { this.x = x; }
private readonly double x;
}
struct Length
{
public static implicit operator Length(double x) { return new Length(x); }
public static implicit operator double(Length length) { return length.x; }
private Length(double x) { this.x = x; }
private readonly double x;
}
Both Area
and Length
are basically a double
, but augment it with a specific meaning. If you defined a method such as…
Area CalculateAreaOfRectangleWith(Length width, Length height)
…it would not be possible to directly pass in an Area
by accident. So far so good.
BUT: You can easily sidestep this apparently improved type safety simply by casting a Area
to double
, or by temporarily storing an Area
in a double
variable, and then passing that into the method where a Length
is expected:
Area a = 10.0;
double aWithEvilPowers = a;
… = CalculateAreaOfRectangleWith( (double)a, aWithEvilPowers );
Question: Does anyone here have experience with extensive use of such custom struct
types in real-world / production software? If so:
Has the wrapping of primitive value types in custom
struct
s ever directly resulted in less bugs, or in more maintainable code, or given any other major advantage(s)?Or are the benefits of custom
struct
s too small for them to be used in practice?
P.S.: About 5 years have passed since I asked this question. I'm posting some of my experiences that I've made since then as a separate answer.