// Copyright (C) Stichting Deltares 2017. All rights reserved.
//
// This file is part of the Macro Stability kernel.
//
// The Macro Stability 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.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Deltares.DamEngine.Data.Standard
{
///
/// Static class ObjectExtensions
///
public static class ObjectExtensions
{
private const double threshold = 0.0000001;
///
/// Tests two double values for equality with a default precision of
///
/// The first double value
/// The other double value to compare with
/// True when almost equal
public static bool AlmostEquals(this double double1, double double2)
{
return AlmostEquals(double1, double2, threshold);
}
///
/// Tests two double values for equality with a given precision
///
/// The first double value
/// The other double value to compare with
/// The precision value
/// True when almost equal
public static bool AlmostEquals(this double double1, double double2, double precision)
{
if (double.IsNaN(double1) && double.IsNaN(double2))
{
return true;
}
if (double.IsNaN(double1) || double.IsNaN(double2))
{
return false;
}
return (Math.Abs(double1 - double2) <= precision);
}
///
/// Clone properties from an original object to a destination object.
///
///
/// Copy matching properties from object to object
/// http://goneale.wordpress.com/2009/02/16/cloning-object-properties-via-reflection/#
///
///
///
///
///
///
public static void CloneProperties(this T1 origin, T2 destination, params string[] excludedProperties)
{
// Instantiate if necessary
if (destination == null)
{
throw new ArgumentNullException("destination", "Destination object must first be instantiated.");
}
// Loop through each property in the destination
foreach (var destinationProperty in destination.GetType().GetProperties())
{
bool excluded = false;
foreach (var excludedProperty in excludedProperties)
{
if (excludedProperty.ToLower().Equals(destinationProperty.Name.ToLower()))
{
excluded = true;
}
}
if (excluded || IsIList(destinationProperty) || IsIDictionary(destinationProperty)
|| IsGenericIList(destinationProperty) || IsGenericIDictionary(destinationProperty))
{
continue;
}
// find and set val if we can find a matching property name and matching type in the origin with the origin's value
if (!origin.Equals(default(T1)) && destinationProperty.CanWrite)
{
PropertyInfo propertyInfo = destinationProperty;
origin.GetType().GetProperties().Where(
x => x.CanRead && (x.Name == propertyInfo.Name && x.PropertyType == propertyInfo.PropertyType))
.ToList()
.ForEach(x => propertyInfo.SetValue(destination, x.GetValue(origin, null), null));
}
}
}
private static bool IsGenericIDictionary(PropertyInfo destinationProperty)
{
return destinationProperty.PropertyType.IsGenericType && destinationProperty.PropertyType.GetGenericTypeDefinition() == typeof(IDictionary<,>);
}
private static bool IsIDictionary(PropertyInfo destinationProperty)
{
return typeof(IDictionary).IsAssignableFrom(destinationProperty.PropertyType);
}
private static bool IsGenericIList(PropertyInfo destinationProperty)
{
return destinationProperty.PropertyType.IsGenericType && destinationProperty.PropertyType.GetGenericTypeDefinition() == typeof(IList<>);
}
private static bool IsIList(PropertyInfo destinationProperty)
{
return typeof(IList).IsAssignableFrom(destinationProperty.PropertyType);
}
}
}