Type-proofing primitive .NET value types via custom structs: Is it worth the effort?

Viewed 1241

I'm toying with the idea of making primitive .NET value types more type-safe and more "self-documenting" by wrapping them in custom structs. 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 structs and so cannot use inheritance to remove code repetition; and since the overloaded operators must be declared static, 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 structs ever directly resulted in less bugs, or in more maintainable code, or given any other major advantage(s)?

  • Or are the benefits of custom structs 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.

5 Answers
Related