Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/ReferenceEqualityComparer.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/ReferenceEqualityComparer.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/ReferenceEqualityComparer.cs (revision 1691) @@ -0,0 +1,84 @@ +// Copyright (C) Stichting Deltares 2018. All rights reserved. +// +// This file is part of the Dam Engine. +// +// The Dam Engine 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. + +// +// This file is retrieved from: +// https://github.com/Burtsev-Alexey/net-object-deep-copy +// +// Source code is released under the MIT license. +// +// The MIT License (MIT) +// Copyright (c) 2014 Burtsev Alexey +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, +// merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be included in all copies +// or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; + +namespace Deltares.DamEngine.Data.Standard +{ + /// + /// Class to compare objects for equality + /// + /// + public class ReferenceEqualityComparer : EqualityComparer + { + /// + /// Determines whether the specified , is equal to this instance. + /// + /// The to compare with this instance. + /// The y. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// + public override bool Equals(object x, object y) + { + return ReferenceEquals(x, y); + } + /// + /// Returns a hash code for this instance. + /// + /// The object. + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// + public override int GetHashCode(object obj) + { + if (obj == null) return 0; + return obj.GetHashCode(); + } + } +} Index: DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Standard/ReferenceEqualityComparerTest.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Standard/ReferenceEqualityComparerTest.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Standard/ReferenceEqualityComparerTest.cs (revision 1691) @@ -0,0 +1,110 @@ +// Copyright (C) Stichting Deltares 2018. All rights reserved. +// +// This file is part of the Delta Shell Light Library. +// +// The Delta Shell Light Library is free software: you can redistribute it and/or modify +// it under the terms of the GNU 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 General Public License for more details. +// +// You should have received a copy of the GNU 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 Deltares.DamEngine.Data.Standard; +using NUnit.Framework; + +namespace Deltares.DamEngine.Data.Tests.Standard +{ + /// + /// Tests to check the reference equality comparer + /// + [TestFixture] + public class ReferenceEqualityComparerTest + { + /// + /// Test for object comparer. + /// + [Test] + public void EqualsTest() + { + var referenceComparer = new ReferenceEqualityComparer(); + + const double doubleValue1 = 1; + const double doubleValue2 = 5; + const int intValue1 = 1; + + bool result = referenceComparer.Equals(doubleValue1.GetType(), doubleValue2.GetType()); + + Assert.IsTrue(result); + + result = referenceComparer.Equals(doubleValue2.GetType(), intValue1.GetType()); + Assert.IsFalse(result); + + + var testPoint1 = new ObjectCopierTest.TestPoint(); + var testPoint2 = new ObjectCopierTest.TestPoint(); + + const double testDouble = new double(); + + result = referenceComparer.Equals(testPoint1.GetType(), testPoint2.GetType()); + Assert.IsTrue(result); + + result = referenceComparer.Equals(testDouble.GetType(), testPoint1.GetType()); + Assert.IsFalse(result); + } + + /// + /// Test for GetHashCode. + /// + [Test] + public void GetHashCodeTest() + { + // initialise constants + var comparer = new ReferenceEqualityComparer(); + + const double doubleValue1 = 1; + const double doubleValue2 = doubleValue1; + const double doubleValue3 = doubleValue1; + const double doubleValue4 = 2; + const double doubleValue5 = 1; + + // get hash codes + int hashCode2 = comparer.GetHashCode(doubleValue2); + int hashCode3 = comparer.GetHashCode(doubleValue3); + int hashCode4 = comparer.GetHashCode(doubleValue4); + int hashCode5 = comparer.GetHashCode(doubleValue5); + + // compare + Assert.AreEqual(hashCode2, hashCode3); + Assert.AreNotEqual(hashCode2, hashCode4); + Assert.AreEqual(hashCode2, hashCode5); + + + // initialise geometry points + var geometryPoint1 = new ObjectCopierTest.TestPoint { X = 1, Z = 1 }; + var geometryPoint2 = new ObjectCopierTest.TestPoint { X = 1, Z = 1 }; + var geometryPoint3 = new ObjectCopierTest.TestPoint { X = 1, Z = 99 }; + var geometryPoint4 = geometryPoint1; + + // get hash codes + int hashCode1 = comparer.GetHashCode(geometryPoint1); + hashCode2 = comparer.GetHashCode(geometryPoint2); + hashCode3 = comparer.GetHashCode(geometryPoint3); + hashCode4 = comparer.GetHashCode(geometryPoint4); + + // compare + Assert.AreNotEqual(hashCode1, hashCode2); + Assert.AreNotEqual(hashCode1, hashCode3); + Assert.AreEqual(hashCode1, hashCode4); + } + } +} Index: DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Deltares.DamEngine.Data.Tests.csproj =================================================================== diff -u -r1641 -r1691 --- DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Deltares.DamEngine.Data.Tests.csproj (.../Deltares.DamEngine.Data.Tests.csproj) (revision 1641) +++ DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Deltares.DamEngine.Data.Tests.csproj (.../Deltares.DamEngine.Data.Tests.csproj) (revision 1691) @@ -32,6 +32,10 @@ MinimumRecommendedRules.ruleset + + False + ..\packages\CompareNETObjects.3.09.0.0\lib\net45\KellermanSoftware.Compare-NET-Objects.dll + False ..\..\lib\NUnit\nunit.framework.dll @@ -50,6 +54,10 @@ + + + + Index: DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Standard/ArrayExtensionsTest.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Standard/ArrayExtensionsTest.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Standard/ArrayExtensionsTest.cs (revision 1691) @@ -0,0 +1,76 @@ +// Copyright (C) Stichting Deltares 2018. All rights reserved. +// +// This file is part of the Delta Shell Light Library. +// +// The Delta Shell Light Library is free software: you can redistribute it and/or modify +// it under the terms of the GNU 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 General Public License for more details. +// +// You should have received a copy of the GNU 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 KellermanSoftware.CompareNetObjects; +using Deltares.DamEngine.Data.Standard; +using NUnit.Framework; + +namespace Deltares.DamEngine.Data.Tests.Standard +{ + /// + /// Tests to check the ArrayExtensions + /// + [TestFixture] + public class ArrayExtensionsTest + { + /// + /// Test to check the ForEach void in ArrayExtensions + /// + [Test] + public void ForEachTest() + { + var compare = new CompareLogic { Config = { MaxDifferences = 100 } }; + + // initialise double array + var doubleArray = new double[5]; + + // assign values to array + doubleArray.ForEach((array, indices) => array.SetValue(5, indices)); + + //assert + for (int i = 0; i < 5; i++) + { + Assert.AreEqual(5, doubleArray[i]); + } + + + // initialise geometryPoint Arrays + var geometryPointArray = new ObjectCopierTest.TestPoint[5]; + var geometryPointArray2 = new ObjectCopierTest.TestPoint[5]; + + // assign values to the first geometryPoint array + for (int i = 0; i < 5; i++) + { + var geometryPoint = new ObjectCopierTest.TestPoint(); + geometryPointArray[i] = geometryPoint; + geometryPointArray[i].X = i; + geometryPointArray[i].Z = i; + } + + // copy the values of the first geometryPoint array to the second geometryPoint array + geometryPointArray2.ForEach((array, indices) => array.SetValue(geometryPointArray.GetValue(indices), indices)); + + var result = compare.Compare(geometryPointArray, geometryPointArray2); + + Assert.AreEqual(0, result.Differences.Count); + } + } +} Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj =================================================================== diff -u -r1649 -r1691 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj (.../Deltares.DamEngine.Data.csproj) (revision 1649) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj (.../Deltares.DamEngine.Data.csproj) (revision 1691) @@ -163,6 +163,7 @@ + @@ -182,7 +183,9 @@ + + Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/ArrayExtensions.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/ArrayExtensions.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/ArrayExtensions.cs (revision 1691) @@ -0,0 +1,102 @@ +// Copyright (C) Stichting Deltares 2018. All rights reserved. +// +// This file is part of the Dam Engine. +// +// The Dam Engine 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. + +// +// This file is retrieved from: +// https://github.com/Burtsev-Alexey/net-object-deep-copy +// +// Source code is released under the MIT license. +// +// The MIT License (MIT) +// Copyright (c) 2014 Burtsev Alexey +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, +// merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be included in all copies +// or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +using System; + +namespace Deltares.DamEngine.Data.Standard +{ + /// + /// Class to perform actions on arrays + /// + public static class ArrayExtensions + { + /// + /// Perform an action for every element in an array + /// + /// The array. + /// The action. + public static void ForEach(this Array array, Action action) + { + if (array.LongLength == 0) return; + var walker = new ArrayTraverse(array); + do action(array, walker.Position); + while (walker.Step()); + } + } + + internal class ArrayTraverse + { + internal int[] Position; + private readonly int[] maxLengths; + + internal ArrayTraverse(Array array) + { + maxLengths = new int[array.Rank]; + for (int i = 0; i < array.Rank; ++i) + { + maxLengths[i] = array.GetLength(i) - 1; + } + Position = new int[array.Rank]; + } + + internal bool Step() + { + for (int i = 0; i < Position.Length; ++i) + { + if (Position[i] < maxLengths[i]) + { + Position[i]++; + for (int j = 0; j < i; j++) + { + Position[j] = 0; + } + return true; + } + } + return false; + } + } +} Index: DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Standard/ObjectCopierTest.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Standard/ObjectCopierTest.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Standard/ObjectCopierTest.cs (revision 1691) @@ -0,0 +1,298 @@ +// Copyright (C) Stichting Deltares 2018. All rights reserved. +// +// This file is part of the Delta Shell Light Library. +// +// The Delta Shell Light Library is free software: you can redistribute it and/or modify +// it under the terms of the GNU 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 General Public License for more details. +// +// You should have received a copy of the GNU 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.Collections.Generic; +using Deltares.DamEngine.Data.Standard; +using KellermanSoftware.CompareNetObjects; +using NUnit.Framework; + +namespace Deltares.DamEngine.Data.Tests.Standard +{ + /// + /// Tests to check the object deep copier + /// + [TestFixture] + public class ObjectCopierTest + { + + internal class TestPoint + { + public double X; + public double Z; + + } + + internal class TestPointDifferentObjects + { + public TestPoint[] TestPointArray = new TestPoint[5]; + public List TestPointList = new List(); + public Dictionary TestPointDictionary = new Dictionary(); + + + /// + /// Assigns the array values. + /// + public void AssignArrayValues() + { + for (int i = 0; i < 5; i++) + { + var testPoint = new TestPoint(); + TestPointArray[i] = testPoint; + TestPointArray[i].X = i; + TestPointArray[i].Z = i + 5; + } + } + + /// + /// Assigns the list values. + /// + public void AssignListValues() + { + for (int i = 0; i < 5; i++) + { + var testPoint = new TestPoint(); + TestPointList.Add(testPoint); + TestPointList[i].X = i; + TestPointList[i].Z = i + 5; + } + } + + /// + /// Assigns the dictionary values. + /// + public void AssignDictionaryValues() + { + for (int i = 0; i < 5; i++) + { + + var testPoint = new TestPoint(); + TestPointDictionary.Add(i, testPoint); + + TestPointDictionary[i].X = i; + TestPointDictionary[i].Z = i + 5; + } + } + } + + /// + /// Copies the class with different properties in arrays test. + /// + [Test] + public void CopyClassWithDifferentPropertiesInArraysTest() + { + // initialise + var differentProperties = new ClassWithDifferentProperties(); + var testPointDifferentObjects = new TestPointDifferentObjects(); + var compare = new CompareLogic { Config = { MaxDifferences = 100 } }; + + differentProperties.AssignArrayValues(); + testPointDifferentObjects.AssignArrayValues(); + + // copy + ClassWithDifferentProperties differentPropertiesCopy = differentProperties.Copy(); + TestPointDifferentObjects testPointDifferentObjectsCopy = testPointDifferentObjects.Copy(); + + // check if copy is done correctly + var result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(0, result.Differences.Count); + + + // change double array + differentPropertiesCopy.DoubleArray[0] = 99; + + result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(1, result.Differences.Count); + Assert.AreNotEqual(differentProperties.DoubleArray[0], differentPropertiesCopy.DoubleArray[0]); + + + // change integer array + differentPropertiesCopy.IntArray[0] = 99; + + result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(2, result.Differences.Count); + Assert.AreNotEqual(differentProperties.IntArray[0], differentPropertiesCopy.IntArray[0]); + + + // change string array + differentPropertiesCopy.StrArray[0] = "99"; + + result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(3, result.Differences.Count); + Assert.AreNotEqual(differentProperties.StrArray[0], differentPropertiesCopy.StrArray[0]); + + + // change boolean array + differentPropertiesCopy.BoolArray[0] = false; + differentPropertiesCopy.BoolArray[1] = false; + + result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(5, result.Differences.Count); + Assert.AreNotEqual(differentProperties.BoolArray[0], differentPropertiesCopy.BoolArray[0]); + Assert.AreNotEqual(differentProperties.BoolArray[1], differentPropertiesCopy.BoolArray[1]); + + + // change geometryPoint array + testPointDifferentObjectsCopy.TestPointArray[1].X = 99; + testPointDifferentObjectsCopy.TestPointArray[1].Z = 99; + + result = compare.Compare(testPointDifferentObjects, testPointDifferentObjectsCopy); + Assert.AreEqual(2, result.Differences.Count); + Assert.AreNotEqual(testPointDifferentObjects.TestPointArray[1].X, testPointDifferentObjectsCopy.TestPointArray[1].X); + Assert.AreNotEqual(testPointDifferentObjects.TestPointArray[1].Z, testPointDifferentObjectsCopy.TestPointArray[1].Z); + } + + + + /// + /// Copies the class with different properties in lists test. + /// + [Test] + public void CopyClassWithDifferentPropertiesInListsTest() + { + // initialise + var differentProperties = new ClassWithDifferentProperties(); + var testPointDifferentObjects = new TestPointDifferentObjects(); + var compare = new CompareLogic { Config = { MaxDifferences = 100 } }; + + differentProperties.AssignListValues(); + testPointDifferentObjects.AssignListValues(); + + // copy + ClassWithDifferentProperties differentPropertiesCopy = differentProperties.Copy(); + TestPointDifferentObjects testPointDifferentObjectsCopy = testPointDifferentObjects.Copy(); + + // check if copy is done correctly + var result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(0, result.Differences.Count); + + + // change double list + differentPropertiesCopy.DoubleList[0] = 99; + + result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(1, result.Differences.Count); + Assert.AreNotEqual(differentProperties.DoubleList[0], differentPropertiesCopy.DoubleList[0]); + + + // change integer list + differentPropertiesCopy.IntList[0] = 99; + + result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(2, result.Differences.Count); + Assert.AreNotEqual(differentProperties.IntList[0], differentPropertiesCopy.IntList[0]); + + + // change string list + differentPropertiesCopy.StrList[0] = "99"; + + result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(3, result.Differences.Count); + Assert.AreNotEqual(differentProperties.StrList[0], differentPropertiesCopy.StrList[0]); + + + // change boolean list + differentPropertiesCopy.BoolList[0] = false; + differentPropertiesCopy.BoolList[1] = false; + + result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(5, result.Differences.Count); + Assert.AreNotEqual(differentProperties.BoolList[0], differentPropertiesCopy.BoolList[0]); + Assert.AreNotEqual(differentProperties.BoolList[1], differentPropertiesCopy.BoolList[1]); + + + // change geometryPoint list + testPointDifferentObjectsCopy.TestPointList[1].X = 99; + testPointDifferentObjectsCopy.TestPointList[1].Z = 99; + + result = compare.Compare(testPointDifferentObjects, testPointDifferentObjectsCopy); + Assert.AreEqual(2, result.Differences.Count); + Assert.AreNotEqual(testPointDifferentObjects.TestPointList[1].X, testPointDifferentObjectsCopy.TestPointList[1].X); + Assert.AreNotEqual(testPointDifferentObjects.TestPointList[1].Z, testPointDifferentObjectsCopy.TestPointList[1].Z); + } + + + /// + /// Copies the class with different properties in dictionaries test. + /// + [Test] + public void CopyClassWithDifferentPropertiesInDictionariesTest() + { + // initialise + var differentProperties = new ClassWithDifferentProperties(); + var testPointDifferentObjects = new TestPointDifferentObjects(); + var compare = new CompareLogic { Config = { MaxDifferences = 100 } }; + + differentProperties.AssignDictionaryValues(); + testPointDifferentObjects.AssignDictionaryValues(); + + // copy + ClassWithDifferentProperties differentPropertiesCopy = differentProperties.Copy(); + TestPointDifferentObjects testPointDifferentObjectsCopy = testPointDifferentObjects.Copy(); + + // check if copy is done correctly + var result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(0, result.Differences.Count); + + // change double dictionary + differentPropertiesCopy.DoubleDictionary[0] = 99; + + result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(1, result.Differences.Count); + Assert.AreNotEqual(differentProperties.DoubleDictionary[0], differentPropertiesCopy.DoubleDictionary[0]); + + + // change integer dictionary + differentPropertiesCopy.IntDictionary[0] = 99; + + result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(2, result.Differences.Count); + Assert.AreNotEqual(differentProperties.IntDictionary[0], differentPropertiesCopy.IntDictionary[0]); + + + // change string dictionary + differentPropertiesCopy.StrDictionary["0"] = "99"; + + result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(3, result.Differences.Count); + Assert.AreNotEqual(differentProperties.StrDictionary["0"], differentPropertiesCopy.StrDictionary["0"]); + + + // change boolean dictionary + differentPropertiesCopy.BoolDictionary[0] = false; + differentPropertiesCopy.BoolDictionary[1] = false; + + result = compare.Compare(differentProperties, differentPropertiesCopy); + Assert.AreEqual(5, result.Differences.Count); + Assert.AreNotEqual(differentProperties.BoolDictionary[0], differentPropertiesCopy.BoolDictionary[0]); + Assert.AreNotEqual(differentProperties.BoolDictionary[1], differentPropertiesCopy.BoolDictionary[1]); + + + // change geometryPoint dictionary + testPointDifferentObjectsCopy.TestPointDictionary[1].X = 99; + testPointDifferentObjectsCopy.TestPointDictionary[1].Z = 99; + + result = compare.Compare(testPointDifferentObjects, testPointDifferentObjectsCopy); + Assert.AreEqual(2, result.Differences.Count); + Assert.AreNotEqual(testPointDifferentObjects.TestPointDictionary[1].X, testPointDifferentObjectsCopy.TestPointDictionary[1].X); + Assert.AreNotEqual(testPointDifferentObjects.TestPointDictionary[1].Z, testPointDifferentObjectsCopy.TestPointDictionary[1].Z); + } + } +} Index: DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Standard/ClassWithDifferentProperties.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Standard/ClassWithDifferentProperties.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Standard/ClassWithDifferentProperties.cs (revision 1691) @@ -0,0 +1,131 @@ +// Copyright (C) Stichting Deltares 2018. All rights reserved. +// +// This file is part of the Delta Shell Light Library. +// +// The Delta Shell Light Library is free software: you can redistribute it and/or modify +// it under the terms of the GNU 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 General Public License for more details. +// +// You should have received a copy of the GNU 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.Collections.Generic; +using System.Globalization; + +namespace Deltares.DamEngine.Data.Tests.Standard +{ + /// + /// Test data object to test ObjectCopier + /// + public class ClassWithDifferentProperties + { + // initilise arrays + + /// + /// The double array + /// + public double[] DoubleArray = new double[5]; + /// + /// The int array + /// + public int[] IntArray = new int[5]; + /// + /// The string array + /// + public string[] StrArray = new string[5]; + /// + /// The bool array + /// + public bool[] BoolArray = new bool[5]; + // initialise lists + /// + /// The double list + /// + public List DoubleList = new List(); + /// + /// The int list + /// + public List IntList = new List(); + /// + /// The string list + /// + public List StrList = new List(); + /// + /// The bool list + /// + public List BoolList = new List(); + // initialise Dictionaries + /// + /// The double dictionary + /// + public Dictionary DoubleDictionary = new Dictionary(); + /// + /// The int dictionary + /// + public Dictionary IntDictionary = new Dictionary(); + /// + /// The string dictionary + /// + public Dictionary StrDictionary = new Dictionary(); + /// + /// The bool dictionary + /// + public Dictionary BoolDictionary = new Dictionary(); + + + + + /// + /// Assigns the array values. + /// + public void AssignArrayValues() + { + for (int i = 0; i < 5; i++) + { + DoubleArray[i] = i; + IntArray[i] = i; + StrArray[i] = i.ToString(CultureInfo.InvariantCulture); + BoolArray[i] = true; + } + } + + + /// + /// Assigns the list values. + /// + public void AssignListValues() + { + for (int i = 0; i < 5; i++) + { + DoubleList.Add(i); + IntList.Add(i); + StrList.Add(i.ToString(CultureInfo.InvariantCulture)); + BoolList.Add(true); + } + } + + /// + /// Assigns the dictionary values. + /// + public void AssignDictionaryValues() + { + for (int i = 0; i < 5; i++) + { + DoubleDictionary.Add(i, i); + IntDictionary.Add(i, i); + StrDictionary.Add(i.ToString(CultureInfo.InvariantCulture), i.ToString(CultureInfo.InvariantCulture)); + BoolDictionary.Add(i, true); + } + } + } +} Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/ObjectCopier.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/ObjectCopier.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/ObjectCopier.cs (revision 1691) @@ -0,0 +1,140 @@ +// Copyright (C) Stichting Deltares 2018. All rights reserved. +// +// This file is part of the Dam Engine. +// +// The Dam Engine 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. + +// +// This file is retrieved from: +// https://github.com/Burtsev-Alexey/net-object-deep-copy +// +// Source code is released under the MIT license. +// +// The MIT License (MIT) +// Copyright (c) 2014 Burtsev Alexey +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, +// merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be included in all copies +// or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace Deltares.DamEngine.Data.Standard +{ + /// + /// Class to handle copying of objects + /// + public static class ObjectCopier + { + private static readonly MethodInfo CloneMethod = typeof(Object).GetMethod("MemberwiseClone", BindingFlags.NonPublic | BindingFlags.Instance); + + /// + /// Determines whether this instance is primitive. + /// + /// The type. + /// + /// true if the specified type is primitive; otherwise, false. + /// + public static bool IsPrimitive(this Type type) + { + if (type == typeof(String)) return true; + return (type.IsValueType & type.IsPrimitive); + } + + /// + /// Copies the specified original object. + /// + /// The original object. + /// + public static Object Copy(Object originalObject) + { + return InternalCopy(originalObject, new Dictionary(new ReferenceEqualityComparer())); + } + private static Object InternalCopy(Object originalObject, IDictionary visited) + { + if (originalObject == null) return null; + var typeToReflect = originalObject.GetType(); + if (IsPrimitive(typeToReflect)) return originalObject; + if (visited.ContainsKey(originalObject)) return visited[originalObject]; + if (typeof(Delegate).IsAssignableFrom(typeToReflect)) return null; + var cloneObject = CloneMethod.Invoke(originalObject, null); + if (typeToReflect.IsArray) + { + var arrayType = typeToReflect.GetElementType(); + if (IsPrimitive(arrayType) == false) + { + var clonedArray = (Array)cloneObject; + clonedArray.ForEach((array, indices) => array.SetValue(InternalCopy(clonedArray.GetValue(indices), visited), indices)); + } + + } + + visited.Add(originalObject, cloneObject); + CopyFields(originalObject, visited, cloneObject, typeToReflect); + RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect); + return cloneObject; + + } + + private static void RecursiveCopyBaseTypePrivateFields(object originalObject, IDictionary visited, object cloneObject, Type typeToReflect) + { + if (typeToReflect.BaseType != null) + { + RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect.BaseType); + CopyFields(originalObject, visited, cloneObject, typeToReflect.BaseType, BindingFlags.Instance | BindingFlags.NonPublic, info => info.IsPrivate); + } + } + + private static void CopyFields(object originalObject, IDictionary visited, object cloneObject, Type typeToReflect, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy, Func filter = null) + { + foreach (FieldInfo fieldInfo in typeToReflect.GetFields(bindingFlags)) + { + if (filter != null && filter(fieldInfo) == false) continue; + if (IsPrimitive(fieldInfo.FieldType)) continue; + var originalFieldValue = fieldInfo.GetValue(originalObject); + var clonedFieldValue = InternalCopy(originalFieldValue, visited); + fieldInfo.SetValue(cloneObject, clonedFieldValue); + } + } + /// + /// Copies the specified original object with specified type. + /// + /// + /// The original. + /// + public static T Copy(this T original) + { + return (T)Copy((Object)original); + } + } +} \ No newline at end of file