NOTE: source code, documentation and binaries have been moved to GitHub (as of release 1.1)

Product description

  • Visual Studio project template for creating Units of Measurement C# class library.
  • Units of measurement are generated from design-time T4 text template according to simple definitions in a text file (data model).
  • Units of measurement are generated as types (namely partial structs). Thus, dimensional analysis can be performed as a syntax check at compile time (dimensional issues displayed in Visual Studio as syntax errors). See the example below.
  • Units of measurement for any of the fundamental dimension i.e.: Length, Time, Mass, Temperature, ElectricCurrent, AmountOfSubstance, LuminousIntensity as well as Other (e.g. Money for currency units) and any of their combinations.
  • Arithmetic (+, ++, -, --, *, /) and comparison (==, !=, <, <=, >, >=) operators to perform calculations directly on quantities of unit type. See the example below.
  • Conversions of quantities to/from other (but compatible) unit types.
See GitHub for more information and downloads.

Example: detecting dimensional issues

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

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 * Math.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 * Math.Sin(angle) + Math.Sqrt((v * Math.Sin(angle)) * (v * Math.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):

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 * UMath.Sin(angle) + UMath.Sqrt((v * UMath.Sin(angle)) * (v * UMath.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).

Last edited Apr 29, 2015 at 7:59 AM by manio, version 18