Skip to content

Detecting dimensional issues (example)

mangh edited this page May 4, 2021 · 3 revisions

Look at the following code sample (taken from Demo/ProjectileRange application):

// RangePlain.cs
double g = 9.80665; // the gravitational acceleration
double v = 715.0;   // the velocity at which the projectile is launched (AK-47)
double h = 0.0;     // the initial height of the projectile
double angle = degrees * PI / 180.0;	// the angle at which the projectile is launched

// the time it takes for the projectile to finish its trajectory:
double tmax = (v * Sin(angle) + Sqrt(v * Sin(angle) * v * Sin(angle) + 2.0 * g * h));

It is hard to see that the expression for tmax is wrong: it expects to get time on the left side but the right side calculates velocity instead (it should be further divided by the acceleration g to be correct, but that was missed somehow). The expression is syntactically correct, compiles without errors, so it might be handed over to production with the problem unnoticed!

Now look at the following example. This time, units of measurement are explicitly used as types of the variables (previously used as plain numbers):

// RangeMeasured.cs
var g = (Meter_Sec2)9.80665; // the gravitational acceleration
var v = (Meter_Sec)715.0;    // the velocity at which the projectile is launched (AK-47)
var h = (Meter)0.0;          // the initial height of the projectile
var angle = (Radian)degrees; // the angle at which the projectile is launched

// the time it takes for the projectile to finish its trajectory:
Second tmax = (v * Sin(angle) + Sqrt(v * Sin(angle) * v * Sin(angle) + 2.0 * g * h));

This time the compiler displays "Cannot implicitly convert type 'Demo.UnitsOfMeasurement.Meter_Sec' to 'Demo.UnitsOfMeasurement.Second'" error message, underlines erroneous statement and stops building with this kind of errors left unresolved.

As you can see, C# strong type checking is not strong enough to detect dimensional inconsistencies, but it can be strengthened by unit of measurement types. Note also that the code with units of measurement applied looks very much like the code based on plain numbers. This may ease switching from one approach (with units) to another (plain numbers).

Clone this wiki locally