Skip to content

Upgrading from 3.x to 4.x

Andreas Gullberg Larsen edited this page Nov 8, 2018 · 13 revisions

The 4.0 release addresses a long wishlist of breaking changes accumulated over the years. The main theme was about binary size so we removed a lot of code we considered unnecessary syntactic sugar, such as number extension methods and nullable factory methods. We also heavily restructured some core types such as splitting up the UnitSystem God-class and addressed behavior we considered incorrect or not optimal.

This document lists the most common upgrade paths we expect you to come across when upgrading.

REQUEST FOR FEEDBACK UNTIL DECEMBER 17!

If you think some of the changes or upgrade paths don't make sense or you wish something was different, please add a comment in the 4.0 pull request while we are in beta. The stable release is scheduled for December 17.

UnitSystem removed

UnitSystem was first split up and removed into more specific classes. Later an entirely new UnitSystem was added to represent a choice of base unit dimensions.

UnitSystem abbreviations => UnitAbbreviationsCache

For looking up or mapping custom unit abbreviations for unit enum types only known at runtime, use UnitAbbreviationsCache instead of UnitSystem:

var abbreviations = UnitAbbreviationsCache.Default;
abbreviations.GetAllUnitAbbreviationsForQuantity(typeof(LengthUnit)); // ["cm", "dm",...]
abbreviations.GetUnitAbbreviations(typeof(LengthUnit), 6); // ["ft", "'", "`"]
abbreviations.GetDefaultAbbreviation(typeof(LengthUnit), 1); // "cm"
abbreviations.MapUnitToAbbreviation(typeof(LengthUnit), 1, new CultureInfo("en-US"), "foo"); // add custom abbreviation for centimeter

Looking up abbreviations for static quantity types, you can use Length.Units as before.

UnitSystem parsing => UnitParser

Dynamic parsing of unit abbreviations, where unit enum type is only known at runtime, is now done by UnitParser:

var parser = UnitParser.Default;
parser.Parse("cm", typeof(LengthUnit)); // 1
parser.TryParse("cm", typeof(LengthUnit), out object val); // returns true, val = 1

For static parsing, you can use Length.ParseUnit("cm") as before.

UnitSystem.DefaultCulture => GlobalConfiguration.DefaultCulture

To change the default culture used by ToString() in quantities:

GlobalConfiguration.DefaultCulture = new CultureInfo("en-US"); // instead of UnitSystem.DefaultCulture

Removed static methods on UnitSystem

Use UnitParser.Default or UnitAbbreviationsCache.Default instead, or create an instance for the culture of your own choice.

Quantity types

Nullable From-methods removed

int? val = null;

// Instead of this
Length? l = Length.FromMeters(val);

// Do this, or create your own convenience factory method
Length? l = val == null ? (Length?)null : Length.FromMeters(val.Value);

Remove unit parameter from ToString() methods

// Instead of
myLength.ToString(LengthUnit.Centimeter); // "100 cm"

// Do this
myLength.ToUnit(LengthUnit.Centimeter).ToString(); // "100 cm"

Stricter parsing

// Instead of
var l = Length.Parse("5ft 3in"); // Throws FormatException

// Do this, special case for feet/inches
var l = Length.ParseFeetInches("5ft 3in");

// Everything else only supports these formats
var l = Length.Parse("1cm");
var l = Length.Parse("1 cm");
var l = Length.Parse("1  cm"); // Multi-space allowed
var l = Length.Parse(" 1 cm "); // Input is trimmed

Change Temperature arithmetic back to use base unit Kelvin

Instead of a special case for Temperature, we now have the exact same arithmetic as for other quantities. Previously subtracting two temperatures would return a TemperatureDelta. Instead, you can now add and subtract two temperatures and they will return a new Temperature with addition/subtraction performed in base unit Kelvin while maintaining the left hand argument's unit.

Temperature celsius30, celsius20; // Assume assigned..

// Before
var x = celsius30 + celsius20; // Not possible
TemperatureDelta deltaCelsius10 = celsius30 - celsius20; // delta 10 degrees Celsius

// After - this can get confusing if you are working with Celsius or Fahrenheit
Temperature celsius323 = celsius30 + celsius20;
Temperature minus263Celsius = celsius30 - celsius20;

// For addition/subtraction when working with Celsius or Fahrenheit, you probably want to use TemperatureDelta
TemperatureDelta deltaCelsius20 = TemperatureDelta.FromDegreesCelsius(20);
Temperature celsius50 = celsius30 + deltaCelsius20;
Temperature celsius10 = celsius30 - deltaCelsius20;

// Or use these convenience methods
Temperature deltaCelsius10 = celsius30.ToDelta(celsius20);
TemperatureDelta deltaCelsius10 = TemperatureDelta.FromTemperatures(celsius30, celsius20);

Length2d removed

Provide your own or use Area if applicable.

Number extension methods removed

Either create your own or use From factory methods.

Length m = 1.Meters(); // No longer possible
Length m = Length.FromMeters(1); // Use this instead