Utilities for using measurements with units. Measurement dimensions are easily constructed from existing dimensions, and new dimensions of measurements with new units can be added. Dimensions are tracked through operations - e.g. a length divided by a time yields a velocity.
Note: All "Units" are defined as
UnitOfMeasurement
s with a value of 1.0 - e.g.Units.Meters
is really aUnitOfMeasurement
object with value 1. In the code,using Unit = Measurements.UnitOfMeasurement;
is often used so that units can be defined sightly more naturally.
Below is an example of using the existing units to calculate hydrostatic pressure in psi.
UnitOfMeasurement g = 9.80665 * Units.MetersPerSecondSquared;
UnitOfMeasurement rho = 1000 * Units.KilogramsPerCubicMeter;
UnitOfMeasurement h = 10000 * Units.Feet;
UnitOfMeasurement pressure = rho * g * h;
Console.WriteLine(pressure.Type.Name + " = " + pressure.ToString(Units.PoundsPerSquareInch);
> Pressure = 4335.28 psi
The dimension of the resulting pressure is detected automatically by keeping track of the UnitOfMeasurement
s tracked through the operations.
Note that units can be combined arbitrarily by multiplication and division. The following code is equivalent to above:
UnitOfMeasurement g = 9.80665 * Units.Meters / (Units.Seconds * Units.Seconds);
UnitOfMeasurement rho = 1000 * Units.Kilograms / (Units.Meters * (Units.Meters * Units.Meters));
UnitOfMeasurement h = 10000 * Units.Feet;
UnitOfMeasurement pressure = rho * g * h;
Console.WriteLine(pressure.Type.Name + " = " + pressure.ToString(Units.PoundsPerSquareInch);
Note: Determination of unit labels is imperfect at the moment. If
Console.WriteLine(pressure.ToString(Units.Pounds / (Units.Inches * Units.Inches)));
were used instead, the resulting output would bePressure = 4335.28 lb/in in
. A named unit should be used for output if a specific resulting label is desired.
The user isn't restricted to the built-in dimensions and units. Consider a new domain: cookie baking.
A baker needs to bake 12 gross cookies (1 gross = 144 cookies) by the end of the week. If he wants to get all of the baking done in a standard 40-hour work week, at what rate must be bake cookies?
// Define new dimensions: a cookie count, which is a base dimension, and a cookie rate, which is a compound dimension using the cookie count and time.
var cookieCount = new Dimension("Cookie Count");
var cookieRate = new Dimension("Cookie Rate", cookieCount / Dimensions.Time);
// Define some cookie units, including specifying the unit to be considered the default SI unit
var cookies = cookieCount.NewSIUnit("cookies");
var dozenCookies = new UnitOfMeasurement("dz", 12 * cookies);
var grossCookies = new UnitOfMeasurement("gr", 144 * cookies);
// Define a new time unit (for this application, workWeek = 40 * Units.Hours would work just as well)
var workWeek = new UnitOfMeasurement("work week", 40 * Units.Hours);
// The baker needs to bake 12 gross cookies
var totalCookies = 12 * grossCookies;
// rate = count / time
var cookiesRate = totalCookies / workWeek;
Console.WriteLine(cookiesRate.ToString("{0:0.000} {1}"));
Console.WriteLine(cookiesRate.ToString(cookies / Units.Minutes));
Console.WriteLine(cookiesRate.ToString("{0:0.0} {1}", dozenCookies / Units.Hours));
> 0.012 cookies/s
> 0.72 cookies/min
> 3.6 dz/hr
Note that the cookieRate
variable is unused (and unnecessary). Because the rate is defined in terms of the base units (namely cookieCount
and Dimensions.Time
) which have SI units defined, the SI units for cookieRate
are defined implicitly. A definition for the SI unit of cookieRate
is only required if a specific label (e.g. cps
) is desired instead of the automatically-generated cookies/s
.