// Copyright (C) Stichting Deltares 2019. All rights reserved.
//
// This file is part of the Dam Macrostability Kernel.
//
// The Dam Macrostability Kernel is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using System.ComponentModel;
using System.Globalization;
namespace Deltares.DamMacroStability.Calculator.Geo
{
public static class ObjectExtensions
{
public static readonly CultureInfo DefaultCulture = new CultureInfo("nl-NL");
public static T ToType(this object value)
{
if (value != null)
return (T) value.ToType(typeof(T), DefaultCulture);
ThrowIfValueType();
return default(T);
}
public static T ToType(this object value, CultureInfo culture)
{
if (value != null)
return (T) value.ToType(typeof(T), culture);
ThrowIfValueType();
return default(T);
}
public static object ToType(this object value, Type type, CultureInfo culture)
{
if (value == null)
{
ThrowIfValueType(type);
return null;
}
if (type.IsEnum)
return value.ToEnumType(type, false);
object obj = null;
if (IsNullable(type))
try
{
type = new NullableConverter(type).UnderlyingType;
obj = Convert.ChangeType(value, type, CultureInfo.InvariantCulture);
}
catch
{
obj = null;
}
else
try
{
if ((type == typeof(double)) && value is string)
{
if (Equals(culture, new CultureInfo("nl-NL")))
{
var str = value as string;
if (str.Contains(",") && !str.Contains("."))
value = str.Replace(",", ".");
else if (str.Contains(",") && str.Contains(".") && (str.Length > 4) && !str.Contains(" "))
value = str.Replace(",", "");
}
obj = value.Equals("NaN")
? double.NaN
: Convert.ChangeType(value, type, CultureInfo.InvariantCulture);
}
else
{
switch (type.Name)
{
case "SByte":
case "Byte":
case "Int16":
case "UInt16":
case "Int32":
case "UInt32":
case "Int64":
case "UInt64":
obj =
Convert.ChangeType(
Convert.ChangeType(value, typeof(double), CultureInfo.InvariantCulture), type);
break;
default:
obj = Convert.ChangeType(value, type, CultureInfo.InvariantCulture);
break;
}
}
}
catch (Exception ex)
{
ThrowConversionException(value, type, ex);
}
return obj;
}
public static T ToEnumType(this object value)
{
if (value == null)
throw new ArgumentNullException("value");
return (T) value.ToEnumType(typeof(T), false);
}
public static object ToEnumType(this object value, Type type, bool ignoreCase = false)
{
if (value == null)
throw new ArgumentNullException("value");
if (!ignoreCase && !Enum.IsDefined(type, value))
ThrowConversionException(value, type, null);
var str = value.ToString();
object obj = null;
try
{
obj = Enum.Parse(type, str, ignoreCase);
}
catch (Exception ex)
{
ThrowConversionException(value, type, ex);
}
return obj;
}
private static void ThrowIfValueType()
{
ThrowIfValueType(typeof(T));
}
private static void ThrowIfValueType(Type type)
{
if (type.IsValueType && !IsNullable(type))
throw new ArgumentNullException(
string.Format("The value can't be null because parameter type {0} is a value type", type));
}
private static bool IsNullable(Type type)
{
if (type.IsGenericType)
return type.GetGenericTypeDefinition() == typeof(Nullable<>);
return false;
}
private static void ThrowConversionException(object value, Type type, Exception e)
{
var str = "";
try
{
str = value.ToString().Replace("\0", " ");
}
catch
{
}
throw new ConversionException(type, str, e);
}
}
}