From b5cf639ba265cf01d5b963eab647ab02ac0329c3 Mon Sep 17 00:00:00 2001 From: Andreas Gullberg Larsen Date: Fri, 28 Sep 2018 22:35:48 +0200 Subject: [PATCH 1/3] Remove static methods of UnitSystem Where an instance method also exists. Add some xmldoc while at it too. --- UnitsNet/CustomCode/UnitSystem.cs | 109 +++++++++++++++++++++--------- 1 file changed, 77 insertions(+), 32 deletions(-) diff --git a/UnitsNet/CustomCode/UnitSystem.cs b/UnitsNet/CustomCode/UnitSystem.cs index 96480fe653..9f21656176 100644 --- a/UnitsNet/CustomCode/UnitSystem.cs +++ b/UnitsNet/CustomCode/UnitSystem.cs @@ -31,6 +31,14 @@ // ReSharper disable once CheckNamespace namespace UnitsNet { + /// + /// Main facade for working with units dynamically and configuring default behavior for quantities' ToString(): + /// - Instance per culture via , for caching number formatting and unit abbreviation localization + /// - Use for local system's current culture + /// - Override to affect number formatting and localization of all quantities' ToString() when culture is not specified + /// - unit abbreviations with dynamic types + /// - Dynamically add abbreviations to unit enums with + /// [PublicAPI] public sealed partial class UnitSystem { @@ -38,11 +46,11 @@ public sealed partial class UnitSystem /// /// Fallback culture used by and - /// + /// /// if no abbreviations are found with current . /// /// - /// User wants to call or with Russian + /// User wants to call or with Russian /// culture, but no translation is defined, so we return the US English definition as a last resort. If it's not /// defined there either, an exception is thrown. /// @@ -147,8 +155,16 @@ public UnitSystem() : this(DefaultCulture) #endif static IFormatProvider DefaultCulture { get; set; } = CultureInfo.CurrentUICulture; + /// + /// Whether this instance is for the . + /// TODO Make this private. + /// public bool IsFallbackCulture => Culture.Equals(FallbackCulture); + /// + /// Clear the cached singleton instances. + /// Calling or afterwards will create a new instance. + /// [PublicAPI] public static void ClearCache() { @@ -185,6 +201,11 @@ public static UnitSystem GetCached([CanBeNull] string cultureName) } // Windows Runtime Component does not allow public methods/ctors with same number of parameters: https://msdn.microsoft.com/en-us/library/br230301.aspx#Overloaded methods + /// + /// Gets or creates the singleton instance configured with localized unit abbreviations and number formatting for the given culture. + /// + /// The culture. + /// The instance. #if WINDOWS_UWP internal #else @@ -205,19 +226,13 @@ static UnitSystem GetCached([CanBeNull] IFormatProvider cultureInfo) } } - [PublicAPI] - // Windows Runtime Component does not allow public methods/ctors with same number of parameters: https://msdn.microsoft.com/en-us/library/br230301.aspx#Overloaded methods -#if WINDOWS_UWP - internal -#else - public -#endif - static TUnitType Parse(string unitAbbreviation, IFormatProvider culture) - where TUnitType : /*Enum constraint hack*/ struct, IComparable, IFormattable - { - return GetCached(culture).Parse(unitAbbreviation); - } - + /// + /// Parses a unit abbreviation for a given unit enumeration type. + /// Example: Parse<LengthUnit>("km") => LengthUnit.Kilometer + /// + /// + /// + /// [PublicAPI] // Windows Runtime Component does not allow public methods/ctors with same number of parameters: https://msdn.microsoft.com/en-us/library/br230301.aspx#Overloaded methods #if WINDOWS_UWP @@ -246,12 +261,10 @@ TUnitType Parse(string unitAbbreviation) [PublicAPI] public object Parse(string unitAbbreviation, Type unitType) { - AbbreviationMap abbrevToUnitValue; - if (!_unitTypeToAbbrevToUnitValue.TryGetValue(unitType, out abbrevToUnitValue)) + if (!_unitTypeToAbbrevToUnitValue.TryGetValue(unitType, out var abbrevToUnitValue)) throw new UnitNotFoundException($"No abbreviations defined for unit type [{unitType}] for culture [{Culture}]."); - List unitIntValues; - List unitValues = abbrevToUnitValue.TryGetValue(unitAbbreviation, out unitIntValues) + List unitValues = abbrevToUnitValue.TryGetValue(unitAbbreviation, out var unitIntValues) ? unitIntValues.Distinct().Cast().ToList() : new List(); @@ -268,19 +281,13 @@ public object Parse(string unitAbbreviation, Type unitType) } } - [PublicAPI] - // Windows Runtime Component does not allow public methods/ctors with same number of parameters: https://msdn.microsoft.com/en-us/library/br230301.aspx#Overloaded methods -#if WINDOWS_UWP - internal -#else - public -#endif - static string GetDefaultAbbreviation(TUnitType unit, CultureInfo culture) - where TUnitType : /*Enum constraint hack*/ struct, IComparable, IFormattable - { - return GetCached(culture).GetDefaultAbbreviation(unit); - } - + /// + /// Gets the default abbreviation for a given unit. If a unit has more than one abbreviation defined, then it returns the first one. + /// Example: GetDefaultAbbreviation<LengthUnit>(LengthUnit.Kilometer) => "km" + /// + /// The unit enum value. + /// The type of unit enum. + /// The default unit abbreviation string. [PublicAPI] // Windows Runtime Component does not allow public methods/ctors with same number of parameters: https://msdn.microsoft.com/en-us/library/br230301.aspx#Overloaded methods #if WINDOWS_UWP @@ -294,12 +301,28 @@ string GetDefaultAbbreviation(TUnitType unit) return GetAllAbbreviations(unit).First(); } + /// + /// Gets the default abbreviation for a given unit type and its numeric enum value. + /// If a unit has more than one abbreviation defined, then it returns the first one. + /// Example: GetDefaultAbbreviation<LengthUnit>(typeof(LengthUnit), 1) => "cm" + /// + /// The unit enum type. + /// The unit enum value. + /// The default unit abbreviation string. [PublicAPI] public string GetDefaultAbbreviation(Type unitType, int unitValue) { return GetAllAbbreviations(unitType, unitValue).First(); } + /// + /// Adds one or more unit abbreviation for the given unit enum value. + /// This is used to dynamically add abbreviations for existing unit enums such as or to extend with third-party unit enums + /// in order to or on them later. + /// + /// The unit enum value. + /// Unit abbreviations to add. + /// The type of unit enum. [PublicAPI] // Windows Runtime Component does not allow public methods/ctors with same number of parameters: https://msdn.microsoft.com/en-us/library/br230301.aspx#Overloaded methods #if WINDOWS_UWP @@ -318,6 +341,14 @@ void MapUnitToAbbreviation(TUnitType unit, params string[] abbreviati MapUnitToAbbreviation(unitType, unitValue, abbreviations); } + /// + /// Adds one or more unit abbreviation for the given unit enum value. + /// This is used to dynamically add abbreviations for existing unit enums such as or to extend with third-party unit enums + /// in order to or on them later. + /// + /// The unit enum type. + /// The unit enum value. + /// Unit abbreviations to add. [PublicAPI] // Windows Runtime Component does not allow public methods/ctors with same number of parameters: https://msdn.microsoft.com/en-us/library/br230301.aspx#Overloaded methods #if WINDOWS_UWP @@ -364,6 +395,13 @@ void MapUnitToAbbreviation(Type unitType, int unitValue, [NotNull] params string } } + /// + /// Try to parse a unit abbreviation. + /// + /// The string value. + /// The unit enum value as out result. + /// Type of unit enum. + /// True if successful. [PublicAPI] // Windows Runtime Component does not allow public methods/ctors with same number of parameters: https://msdn.microsoft.com/en-us/library/br230301.aspx#Overloaded methods #if WINDOWS_UWP @@ -386,6 +424,13 @@ bool TryParse(string unitAbbreviation, out TUnitType unit) } } + /// + /// Try to parse a unit abbreviation. + /// + /// The string value. + /// Type of unit enum. + /// The unit enum value as out result. + /// True if successful. [PublicAPI] public bool TryParse(string unitAbbreviation, Type unitType, out object unit) { From 5202adcc05d968bfa6f7ab9f4edb42bd9f24bef2 Mon Sep 17 00:00:00 2001 From: Andreas Gullberg Larsen Date: Fri, 28 Sep 2018 22:37:28 +0200 Subject: [PATCH 2/3] Make IsFallbackCulture private I can't see how this is used externally? --- UnitsNet/CustomCode/UnitSystem.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/UnitsNet/CustomCode/UnitSystem.cs b/UnitsNet/CustomCode/UnitSystem.cs index 9f21656176..e4dbfaf4ce 100644 --- a/UnitsNet/CustomCode/UnitSystem.cs +++ b/UnitsNet/CustomCode/UnitSystem.cs @@ -157,9 +157,8 @@ public UnitSystem() : this(DefaultCulture) /// /// Whether this instance is for the . - /// TODO Make this private. /// - public bool IsFallbackCulture => Culture.Equals(FallbackCulture); + private bool IsFallbackCulture => Culture.Equals(FallbackCulture); /// /// Clear the cached singleton instances. From 0e3dba32912ebf8bd9aaec1be991e13e412ab06d Mon Sep 17 00:00:00 2001 From: Tristan Milnthorp Date: Mon, 1 Oct 2018 10:37:03 -0400 Subject: [PATCH 3/3] Use FallbackCulture rather than re-defining en-US --- UnitsNet/CustomCode/UnitSystem.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/UnitsNet/CustomCode/UnitSystem.cs b/UnitsNet/CustomCode/UnitSystem.cs index e4dbfaf4ce..ea3f4bac28 100644 --- a/UnitsNet/CustomCode/UnitSystem.cs +++ b/UnitsNet/CustomCode/UnitSystem.cs @@ -528,12 +528,11 @@ private void LoadDefaultAbbreviations([NotNull] IFormatProvider culture) foreach (CulturesForEnumValue ev in localization.EnumValues) { int unitEnumValue = ev.Value; - var usCulture = new CultureInfo("en-US"); // Fall back to US English if localization not found - AbbreviationsForCulture matchingCulture = + var matchingCulture = ev.Cultures.FirstOrDefault(a => a.Cult.Equals(culture)) ?? - ev.Cultures.FirstOrDefault(a => a.Cult.Equals(usCulture)); + ev.Cultures.FirstOrDefault(a => a.Cult.Equals(FallbackCulture)); if (matchingCulture == null) continue;