From f0f346056a403b713564d11179267ec70f5543e4 Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Sat, 18 Apr 2020 14:23:56 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=90=20Add=20culture-specific=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- X10D/src/ConvertibleExtensions.cs | 120 ++++++++++++++++-------------- X10D/src/TimeSpanParser.cs | 15 ++-- 2 files changed, 74 insertions(+), 61 deletions(-) diff --git a/X10D/src/ConvertibleExtensions.cs b/X10D/src/ConvertibleExtensions.cs index 51e7b97..316a293 100644 --- a/X10D/src/ConvertibleExtensions.cs +++ b/X10D/src/ConvertibleExtensions.cs @@ -11,46 +11,57 @@ /// Converts the object to another type. /// /// The type to convert to. - /// The object to convert. + /// The object to convert. + /// An object that supplies culture-specific formatting information. /// Returns the value converted to . - public static T To(this IConvertible obj) + /// This conversion is not supported. + /// -or- + /// is and is a value type. + public static T To(this IConvertible value, IFormatProvider provider = null) { - return (T) Convert.ChangeType(obj, typeof(T)); - } - - /// - /// Converts the object to another type, returning the default value on failure. - /// - /// The type to convert to. - /// The object to convert. - /// Returns the value converted to . - public static T ToOrDefault(this IConvertible obj) - { - try - { - return To(obj); - } - catch + if (value is null) { return default; } + + return (T)Convert.ChangeType(value, typeof(T), provider); } /// /// Converts the object to another type, returning the default value on failure. /// /// The type to convert to. - /// The object to convert. - /// The parameter where the result should be sent. - /// Returns on success, on failure. - public static bool ToOrDefault(this IConvertible obj, out T newObj) + /// The object to convert. + /// The format provider. + /// Returns the value converted to . + /// This conversion is not supported. + public static T ToOrDefault(this IConvertible value, IFormatProvider provider = null) { + return value is null ? default : To(value, provider); + } + + /// + /// Converts the object to another type, returning the default value on failure. + /// + /// The type to convert to. + /// The object to convert. + /// The parameter where the result should be sent. + /// An object that supplies culture-specific formatting information. + /// Returns on success, on failure. + public static bool ToOrDefault(this IConvertible value, out T newObj, IFormatProvider provider = null) + { + if (value is null) + { + newObj = default; + return false; + } + try { - newObj = To(obj); + newObj = To(value, provider); return true; } - catch + catch (InvalidCastException) { newObj = default; return false; @@ -61,16 +72,22 @@ /// Converts the object to another type, returning a different value on failure. /// /// The type to convert to. - /// The object to convert. + /// The object to convert. /// The backup value. + /// An object that supplies culture-specific formatting information. /// Returns the value converted to . - public static T ToOrOther(this IConvertible obj, T other) + public static T ToOrOther(this IConvertible value, T other, IFormatProvider provider = null) { + if (value is null) + { + return other; + } + try { - return To(obj); + return To(value, provider); } - catch + catch (Exception ex) when (ex is InvalidCastException || ex is FormatException) { return other; } @@ -80,18 +97,25 @@ /// Converts the object to another type, returning a different value on failure. /// /// The type to convert to. - /// The object to convert. + /// The object to convert. /// The parameter where the result should be sent. /// The backup value. + /// An object that supplies culture-specific formatting information. /// Returns on success, on failure. - public static bool ToOrOther(this IConvertible obj, out T newObj, T other) + public static bool ToOrOther(this IConvertible value, out T newObj, T other, IFormatProvider provider = null) { + if (value is null) + { + newObj = other; + return false; + } + try { - newObj = To(obj); + newObj = To(value, provider); return true; } - catch + catch (Exception ex) when (ex is InvalidCastException || ex is FormatException) { newObj = other; return false; @@ -102,39 +126,27 @@ /// Converts the object to another type, returning on failure. /// /// The type to convert to. - /// The object to convert. + /// The object to convert. + /// An object that supplies culture-specific formatting information. /// Returns a or . - public static T ToOrNull(this IConvertible obj) where T : class + public static T ToOrNull(this IConvertible value, IFormatProvider provider = null) + where T : class { - try - { - return To(obj); - } - catch - { - return null; - } + return value.ToOrNull(out T v, provider) ? v : null; } /// /// Converts the object to another type, returning on failure. /// /// The type to convert to. - /// The object to convert. + /// The object to convert. /// The parameter where the result should be sent. + /// An object that supplies culture-specific formatting information. /// Returns a or . - public static bool ToOrNull(this IConvertible obj, out T newObj) where T : class + public static bool ToOrNull(this IConvertible value, out T newObj, IFormatProvider provider = null) + where T : class { - try - { - newObj = To(obj); - return true; - } - catch - { - newObj = null; - return false; - } + return ToOrOther(value, out newObj, null, provider); } } } diff --git a/X10D/src/TimeSpanParser.cs b/X10D/src/TimeSpanParser.cs index c8517a2..54ac8f8 100644 --- a/X10D/src/TimeSpanParser.cs +++ b/X10D/src/TimeSpanParser.cs @@ -11,8 +11,9 @@ /// . /// /// The input string. + /// The format provider. /// Returns an instance of . - public static TimeSpan Parse(string input) + public static TimeSpan Parse(string input, IFormatProvider provider = null) { const string realNumberPattern = @"([0-9]*\.[0-9]+|[0-9]+)"; string pattern = $@"^(?:{realNumberPattern} *w)? *" + @@ -27,32 +28,32 @@ if (match.Groups[1].Success) { - weeks = double.Parse(match.Groups[1].Value); + weeks = double.Parse(match.Groups[1].Value, provider); } if (match.Groups[2].Success) { - days = double.Parse(match.Groups[2].Value); + days = double.Parse(match.Groups[2].Value, provider); } if (match.Groups[3].Success) { - hours = double.Parse(match.Groups[3].Value); + hours = double.Parse(match.Groups[3].Value, provider); } if (match.Groups[4].Success) { - minutes = double.Parse(match.Groups[4].Value); + minutes = double.Parse(match.Groups[4].Value, provider); } if (match.Groups[5].Success) { - seconds = double.Parse(match.Groups[5].Value); + seconds = double.Parse(match.Groups[5].Value, provider); } if (match.Groups[6].Success) { - milliseconds = double.Parse(match.Groups[6].Value); + milliseconds = double.Parse(match.Groups[6].Value, provider); } Trace.WriteLine($"Input: {input}");