Quantify is a framework that strives to make it easier, to handle quantities with different units in your .NET based applications.
- Based on .NET Standard 1.0 for increased compatibility.
- Include quantities in calculations with both primitives and other quantities of the same unit.
- Convert quantities from one unit to another.
- Make you own quantity that suit your needs.
- Supports enum based units with static unit values and units with dynamic values by implementing your own UnitRepository.
Quantify combines a value and a unit into a quantity.
var height = Length.Create(1.89, Unit.Metre);
Quantities can easily be converted from on unit to another.
var distanceInMetres = Length.Create(1250, Unit.Metre);
var distanceInKilometres = distanceInMetres.ToUnit(Unit.Kilometre);
var distance = distanceInKilometres.Value; // distance = 1.25 kilometres
Quantify quantities supports basic arithmetic operations with primitives. These operations are available as both methods and operators.
var distanceToMall = Length.Create(2.22, Unit.Kilometre);
var distanceBothWays = distanceToMall * 2; // distanceBothWays = 4.44 kolimetres
Quantify quantities also support basic arithmetic arithmetic with other quantities. These operations are available as both methods and operators.
var swimmingDistance = Length.Create(3.86, Unit.Kilometre);
var bikingDistance = Length.Create(180.25, Unit.Kilometre);
var runningDistance = Length.Create(42.20, Unit.Kilometre);
var totalIronman = swimmingDistance + bikingDistance + runningDistance;
// OR
var totalIronman = swimmingDistance.Add(bikingDistance).Add(runningDistance);
When multiple quantities with different units are involved in an operation, the result of the operation is always of the same type, as the quantity on the left hand side of the operation.
var distanceFromWorkToHome = Length.Create(62.5, Unit.Kilometre);
var distanceFromHomeToPool = Length.Create(102, Unit.Feet);
var totalDistanceFromWorkToPool = distanceFromWorkToHome + distanceFromHomeToPool;
In this case the quantity totalDistanceFromWorkToPool
is in kilometres.
Name | Status | Description |
---|---|---|
Quantify.Length | Airborn | Work with quantities representing lengths |
Quantify.Area | Planned | Work with quantities representing areas |
Quantify.Volume | Planned | Work with quantities representing volumes |
Quantify.Weight | Planned | Work with quantities representing weights |
Quantify.Extensions.Area | Planned | Adds support for the multiplication operator between two Quantify.Length's, the result of which is an instance of Quantify.Area |
Quantify.Extensions.Volume | Planned | Adds support for the multiplication operator between a Quantify.Area and a Quantify.Length, the result of which is an instance of Quantify.Volume |
If non of the existing Quantify implementations suits your needs, you can easily implement your own in little to no time. All your need is this core library and a unit repository.
Start by installing the Nuget package Quantify.
Create a new class the custom quantity. This class must inherit the abstract class Quantity
.
public sealed class CustomQuantity : Quantity<double, Unit, CustomQuantity>
{
private CustomQuantity(double value, Unit unit, UnitRepository<Unit> unitRepository) : base(value, unit, unitRepository)
{
}
private CustomQuantity(double value, Unit unit, UnitRepository<Unit> unitRepository, ValueCalculator<double> valueCalculator, ValueConverter<double, Unit> valueConverter) : base(value, unit, unitRepository, valueCalculator, valueConverter)
{
}
public static CustomQuantity Create(double value, Unit unit)
{
var unitRepository = new EnumUnitRepository<Unit>();
return new Length(value, unit, unitRepository);
}
protected override CustomQuantity CreateInstance(double value, Unit unit, UnitRepository<Unit> unitRepository, ValueCalculator<double> valueCalculator, ValueConverter<double, Unit> valueConverter)
{
return new CustomQuantity(value, unit, unitRepository, valueCalculator, valueConverter);
}
}
The abstract class Quantity
has three generic arguments.
- The first argument defines the type of the value stored in the quantity. The supported types are
double
anddecimal
so far. - The second argument defines the type of the unit stored in the quantity. In this case it's an enum, but it might as well be a string, an int or an object. This type is the same type your unit repository use to retrive information about a specific unit.
- The third argument is the quantity class itself.
If your unit values are static, universal constants, like length and weight units, and if you plan on using an enum to represent unit values, then Quantify.Repository.Enum might be useful. This library contains a complete implementation of an enum based unit repository. Please refer to the documentation for more details.
To implement a custom unit repository, create a new class that implements the interface UnitRepository.
public class CustomUnitRepository : UnitRepository<string> {
public double? GetUnitValueInBaseUnits(string unit) {
// Fetch unit value in base units
}
public decimal? GetPreciseUnitValueInBaseUnits(TUnit unit) {
// Fetch precise unit value in base units
}
}
The interface defines two methods. Both methods must return the unit value in base units, for the requested unit. For example, if the SI unit metre is the base unit, then a request for the SI unit kilometre would return 1000, since 1 kilometre represents 1000 base units (metres).
GetUnitValueInBaseUnits
returns the unit value in base units as a double
. This is for use in calculations where performance is favored above precision. The opposite is true for GetPreciseUnitValueInBaseUnits
. This method return the unit value in base units as a decimal
. This is for use in calculations where precision is favored above performance.
© Copyright 2020 Michel Gammelgaard. All rights reserved. Provided under the MIT license. Flask disk icon by Michel Gammelgaard. © Copyright 2020 Michel Gammelgaard. All rights reserved.