// 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); } } }