🌐 Add culture-specific support

This commit is contained in:
Oliver Booth 2020-04-18 14:23:56 +01:00
parent 5f8458f185
commit f0f346056a
No known key found for this signature in database
GPG Key ID: 0D7F2EF1C8D2B9C0
2 changed files with 74 additions and 61 deletions

View File

@ -11,46 +11,57 @@
/// Converts the object to another type.
/// </summary>
/// <typeparam name="T">The type to convert to.</typeparam>
/// <param name="obj">The object to convert.</param>
/// <param name="value">The object to convert.</param>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <returns>Returns the value converted to <see cref="T"/>.</returns>
public static T To<T>(this IConvertible obj)
/// <exception cref="InvalidCastException">This conversion is not supported.
/// -or-
/// <paramref name="value"/> is <see langword="null"/> and <typeparamref name="T"/> is a value type.</exception>
public static T To<T>(this IConvertible value, IFormatProvider provider = null)
{
return (T) Convert.ChangeType(obj, typeof(T));
}
/// <summary>
/// Converts the object to another type, returning the default value on failure.
/// </summary>
/// <typeparam name="T">The type to convert to.</typeparam>
/// <param name="obj">The object to convert.</param>
/// <returns>Returns the value converted to <see cref="T"/>.</returns>
public static T ToOrDefault<T>(this IConvertible obj)
{
try
{
return To<T>(obj);
}
catch
if (value is null)
{
return default;
}
return (T)Convert.ChangeType(value, typeof(T), provider);
}
/// <summary>
/// Converts the object to another type, returning the default value on failure.
/// </summary>
/// <typeparam name="T">The type to convert to.</typeparam>
/// <param name="obj">The object to convert.</param>
/// <param name="newObj">The parameter where the result should be sent.</param>
/// <returns>Returns <see langword="true"/> on success, <see langword="true"/> on failure.</returns>
public static bool ToOrDefault<T>(this IConvertible obj, out T newObj)
/// <param name="value">The object to convert.</param>
/// <param name="provider">The format provider.</param>
/// <returns>Returns the value converted to <see cref="T"/>.</returns>
/// <exception cref="InvalidCastException">This conversion is not supported.</exception>
public static T ToOrDefault<T>(this IConvertible value, IFormatProvider provider = null)
{
return value is null ? default : To<T>(value, provider);
}
/// <summary>
/// Converts the object to another type, returning the default value on failure.
/// </summary>
/// <typeparam name="T">The type to convert to.</typeparam>
/// <param name="value">The object to convert.</param>
/// <param name="newObj">The parameter where the result should be sent.</param>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <returns>Returns <see langword="true"/> on success, <see langword="true"/> on failure.</returns>
public static bool ToOrDefault<T>(this IConvertible value, out T newObj, IFormatProvider provider = null)
{
if (value is null)
{
newObj = default;
return false;
}
try
{
newObj = To<T>(obj);
newObj = To<T>(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.
/// </summary>
/// <typeparam name="T">The type to convert to.</typeparam>
/// <param name="obj">The object to convert.</param>
/// <param name="value">The object to convert.</param>
/// <param name="other">The backup value.</param>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <returns>Returns the value converted to <see cref="T"/>.</returns>
public static T ToOrOther<T>(this IConvertible obj, T other)
public static T ToOrOther<T>(this IConvertible value, T other, IFormatProvider provider = null)
{
if (value is null)
{
return other;
}
try
{
return To<T>(obj);
return To<T>(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.
/// </summary>
/// <typeparam name="T">The type to convert to.</typeparam>
/// <param name="obj">The object to convert.</param>
/// <param name="value">The object to convert.</param>
/// <param name="newObj">The parameter where the result should be sent.</param>
/// <param name="other">The backup value.</param>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <returns>Returns <see langword="true"/> on success, <see langword="true"/> on failure.</returns>
public static bool ToOrOther<T>(this IConvertible obj, out T newObj, T other)
public static bool ToOrOther<T>(this IConvertible value, out T newObj, T other, IFormatProvider provider = null)
{
if (value is null)
{
newObj = other;
return false;
}
try
{
newObj = To<T>(obj);
newObj = To<T>(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 <see langword="null"/> on failure.
/// </summary>
/// <typeparam name="T">The type to convert to.</typeparam>
/// <param name="obj">The object to convert.</param>
/// <param name="value">The object to convert.</param>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <returns>Returns a <see cref="T"/> or <see langword="null"/>.</returns>
public static T ToOrNull<T>(this IConvertible obj) where T : class
public static T ToOrNull<T>(this IConvertible value, IFormatProvider provider = null)
where T : class
{
try
{
return To<T>(obj);
}
catch
{
return null;
}
return value.ToOrNull(out T v, provider) ? v : null;
}
/// <summary>
/// Converts the object to another type, returning <see langword="null"/> on failure.
/// </summary>
/// <typeparam name="T">The type to convert to.</typeparam>
/// <param name="obj">The object to convert.</param>
/// <param name="value">The object to convert.</param>
/// <param name="newObj">The parameter where the result should be sent.</param>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <returns>Returns a <see cref="T"/> or <see langword="null"/>.</returns>
public static bool ToOrNull<T>(this IConvertible obj, out T newObj) where T : class
public static bool ToOrNull<T>(this IConvertible value, out T newObj, IFormatProvider provider = null)
where T : class
{
try
{
newObj = To<T>(obj);
return true;
}
catch
{
newObj = null;
return false;
}
return ToOrOther(value, out newObj, null, provider);
}
}
}

View File

@ -11,8 +11,9 @@
/// <see cref="TimeSpan"/>.
/// </summary>
/// <param name="input">The input string.</param>
/// <param name="provider">The format provider.</param>
/// <returns>Returns an instance of <see cref="TimeSpan"/>.</returns>
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}");