diff --git a/Nuclex.Support (net-4.0).csproj b/Nuclex.Support (net-4.0).csproj
index 85e2d5b..9b94dc3 100644
--- a/Nuclex.Support (net-4.0).csproj
+++ b/Nuclex.Support (net-4.0).csproj
@@ -348,11 +348,11 @@
-
\ No newline at end of file
diff --git a/Nuclex.Support (net-4.6).csproj b/Nuclex.Support (net-4.6).csproj
index 7dac898..06b3d2c 100644
--- a/Nuclex.Support (net-4.6).csproj
+++ b/Nuclex.Support (net-4.6).csproj
@@ -351,11 +351,11 @@
-
\ No newline at end of file
diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs
index 204363e..4b45d5d 100644
--- a/Properties/AssemblyInfo.cs
+++ b/Properties/AssemblyInfo.cs
@@ -1,37 +1,56 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Nuclex.Support")]
-[assembly: AssemblyProduct("Nuclex.Support")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyCompany("Nuclex Development Labs")]
-[assembly: AssemblyCopyright("Copyright © Nuclex Development Labs 2008-2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("1308e4c3-a0c1-423a-aaae-61c7314777e0")]
-
-#if UNITTEST
-// This is required to NMock can derive its proxies from interfaces in
-// the internal unit test classes
-[assembly: InternalsVisibleTo(NMock.Constants.InternalsVisibleToDynamicProxy)]
-#endif
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-[assembly: AssemblyVersion("1.0.0.0")]
+#region Apache License 2.0
+/*
+Nuclex .NET Framework
+Copyright (C) 2002-2024 Markus Ewald / Nuclex Development Labs
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#endregion // Apache License 2.0
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Nuclex.Support")]
+[assembly: AssemblyProduct("Nuclex.Support")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyCompany("Nuclex Development Labs")]
+[assembly: AssemblyCopyright("Copyright © Markus Ewald / Nuclex Development Labs 2002-2024")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("1308e4c3-a0c1-423a-aaae-61c7314777e0")]
+
+#if UNITTEST
+// This is required to NMock can derive its proxies from interfaces in
+// the internal unit test classes
+[assembly: InternalsVisibleTo(NMock.Constants.InternalsVisibleToDynamicProxy)]
+#endif
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/Source/Async/AsyncStatus.cs b/Source/Async/AsyncStatus.cs
old mode 100755
new mode 100644
index 3b53c08..8cb0d59
--- a/Source/Async/AsyncStatus.cs
+++ b/Source/Async/AsyncStatus.cs
@@ -1,22 +1,21 @@
-#region CPL License
+#region Apache License 2.0
/*
-Nuclex Framework
-Copyright (C) 2002-2017 Nuclex Development Labs
+Nuclex .NET Framework
+Copyright (C) 2002-2024 Markus Ewald / Nuclex Development Labs
-This library is free software; you can redistribute it and/or
-modify it under the terms of the IBM Common Public License as
-published by the IBM Corporation; either version 1.0 of the
-License, or (at your option) any later version.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
-This library 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
-IBM Common Public License for more details.
+ http://www.apache.org/licenses/LICENSE-2.0
-You should have received a copy of the IBM Common Public
-License along with this library
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
-#endregion
+#endregion // Apache License 2.0
using System;
diff --git a/Source/Async/AsyncStatusEventArgs.cs b/Source/Async/AsyncStatusEventArgs.cs
old mode 100755
new mode 100644
index 3ef0319..106746f
--- a/Source/Async/AsyncStatusEventArgs.cs
+++ b/Source/Async/AsyncStatusEventArgs.cs
@@ -1,22 +1,21 @@
-#region CPL License
+#region Apache License 2.0
/*
-Nuclex Framework
-Copyright (C) 2002-2017 Nuclex Development Labs
+Nuclex .NET Framework
+Copyright (C) 2002-2024 Markus Ewald / Nuclex Development Labs
-This library is free software; you can redistribute it and/or
-modify it under the terms of the IBM Common Public License as
-published by the IBM Corporation; either version 1.0 of the
-License, or (at your option) any later version.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
-This library 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
-IBM Common Public License for more details.
+ http://www.apache.org/licenses/LICENSE-2.0
-You should have received a copy of the IBM Common Public
-License along with this library
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
-#endregion
+#endregion // Apache License 2.0
using System;
diff --git a/Source/Async/IAsyncAction.cs b/Source/Async/IAsyncAction.cs
old mode 100755
new mode 100644
index 7e47f71..b952062
--- a/Source/Async/IAsyncAction.cs
+++ b/Source/Async/IAsyncAction.cs
@@ -1,22 +1,21 @@
-#region CPL License
+#region Apache License 2.0
/*
-Nuclex Framework
-Copyright (C) 2002-2017 Nuclex Development Labs
+Nuclex .NET Framework
+Copyright (C) 2002-2024 Markus Ewald / Nuclex Development Labs
-This library is free software; you can redistribute it and/or
-modify it under the terms of the IBM Common Public License as
-published by the IBM Corporation; either version 1.0 of the
-License, or (at your option) any later version.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
-This library 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
-IBM Common Public License for more details.
+ http://www.apache.org/licenses/LICENSE-2.0
-You should have received a copy of the IBM Common Public
-License along with this library
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
-#endregion
+#endregion // Apache License 2.0
using System;
using System.Threading;
diff --git a/Source/Async/IAsyncSwitch.cs b/Source/Async/IAsyncSwitch.cs
old mode 100755
new mode 100644
index 80f74b5..bc7935a
--- a/Source/Async/IAsyncSwitch.cs
+++ b/Source/Async/IAsyncSwitch.cs
@@ -1,22 +1,21 @@
-#region CPL License
+#region Apache License 2.0
/*
-Nuclex Framework
-Copyright (C) 2002-2017 Nuclex Development Labs
+Nuclex .NET Framework
+Copyright (C) 2002-2024 Markus Ewald / Nuclex Development Labs
-This library is free software; you can redistribute it and/or
-modify it under the terms of the IBM Common Public License as
-published by the IBM Corporation; either version 1.0 of the
-License, or (at your option) any later version.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
-This library 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
-IBM Common Public License for more details.
+ http://www.apache.org/licenses/LICENSE-2.0
-You should have received a copy of the IBM Common Public
-License along with this library
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
-#endregion
+#endregion // Apache License 2.0
using System;
using System.Threading;
diff --git a/Source/Async/IAsyncTask.cs b/Source/Async/IAsyncTask.cs
old mode 100755
new mode 100644
index 1cb7ed4..f77459f
--- a/Source/Async/IAsyncTask.cs
+++ b/Source/Async/IAsyncTask.cs
@@ -1,22 +1,21 @@
-#region CPL License
+#region Apache License 2.0
/*
-Nuclex Framework
-Copyright (C) 2002-2017 Nuclex Development Labs
+Nuclex .NET Framework
+Copyright (C) 2002-2024 Markus Ewald / Nuclex Development Labs
-This library is free software; you can redistribute it and/or
-modify it under the terms of the IBM Common Public License as
-published by the IBM Corporation; either version 1.0 of the
-License, or (at your option) any later version.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
-This library 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
-IBM Common Public License for more details.
+ http://www.apache.org/licenses/LICENSE-2.0
-You should have received a copy of the IBM Common Public
-License along with this library
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
-#endregion
+#endregion // Apache License 2.0
using System;
diff --git a/Source/Async/ICancellable.cs b/Source/Async/ICancellable.cs
old mode 100755
new mode 100644
index 49292c2..5aca48d
--- a/Source/Async/ICancellable.cs
+++ b/Source/Async/ICancellable.cs
@@ -1,22 +1,21 @@
-#region CPL License
+#region Apache License 2.0
/*
-Nuclex Framework
-Copyright (C) 2002-2017 Nuclex Development Labs
+Nuclex .NET Framework
+Copyright (C) 2002-2024 Markus Ewald / Nuclex Development Labs
-This library is free software; you can redistribute it and/or
-modify it under the terms of the IBM Common Public License as
-published by the IBM Corporation; either version 1.0 of the
-License, or (at your option) any later version.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
-This library 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
-IBM Common Public License for more details.
+ http://www.apache.org/licenses/LICENSE-2.0
-You should have received a copy of the IBM Common Public
-License along with this library
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
-#endregion
+#endregion // Apache License 2.0
using System;
diff --git a/Source/Async/IProgressSource.cs b/Source/Async/IProgressSource.cs
old mode 100755
new mode 100644
index 8cc1bdf..947ce1a
--- a/Source/Async/IProgressSource.cs
+++ b/Source/Async/IProgressSource.cs
@@ -1,22 +1,21 @@
-#region CPL License
+#region Apache License 2.0
/*
-Nuclex Framework
-Copyright (C) 2002-2017 Nuclex Development Labs
+Nuclex .NET Framework
+Copyright (C) 2002-2024 Markus Ewald / Nuclex Development Labs
-This library is free software; you can redistribute it and/or
-modify it under the terms of the IBM Common Public License as
-published by the IBM Corporation; either version 1.0 of the
-License, or (at your option) any later version.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
-This library 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
-IBM Common Public License for more details.
+ http://www.apache.org/licenses/LICENSE-2.0
-You should have received a copy of the IBM Common Public
-License along with this library
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
-#endregion
+#endregion // Apache License 2.0
using System;
diff --git a/Source/Cloning/CloneFactoryTest.cs b/Source/Cloning/CloneFactoryTest.cs
index afe222c..3a4f1f4 100644
--- a/Source/Cloning/CloneFactoryTest.cs
+++ b/Source/Cloning/CloneFactoryTest.cs
@@ -1,597 +1,596 @@
-#region CPL License
-/*
-Nuclex Framework
-Copyright (C) 2002-2017 Nuclex Development Labs
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the IBM Common Public License as
-published by the IBM Corporation; either version 1.0 of the
-License, or (at your option) any later version.
-
-This library 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
-IBM Common Public License for more details.
-
-You should have received a copy of the IBM Common Public
-License along with this library
-*/
-#endregion
-
-#if UNITTEST
-
-using System;
-
-using NUnit.Framework;
-
-namespace Nuclex.Support.Cloning {
-
- /// Base class for unit tests verifying the clone factory
- internal abstract class CloneFactoryTest {
-
- #region class DerivedReferenceType
-
- /// A derived reference type being used for testing
- protected class DerivedReferenceType : TestReferenceType {
-
- /// Field holding an integer value for testing
- public int DerivedField;
- /// Property holding an integer value for testing
- public int DerivedProperty { get; set; }
-
- }
-
- #endregion // class DerivedReferenceType
-
- #region class TestReferenceType
-
- /// A reference type being used for testing
- protected class TestReferenceType {
-
- /// Field holding an integer value for testing
- public int TestField;
- /// Property holding an integer value for testing
- public int TestProperty { get; set; }
-
- }
-
- #endregion // class TestReferenceType
-
- #region struct TestValueType
-
- /// A value type being used for testing
- protected struct TestValueType {
-
- /// Field holding an integer value for testing
- public int TestField;
- /// Property holding an integer value for testing
- public int TestProperty { get; set; }
-
- }
-
- #endregion // struct TestValueType
-
- #region struct HierarchicalValueType
-
- /// A value type containiner other complex types used for testing
- protected struct HierarchicalValueType {
-
- /// Field holding an integer value for testing
- public int TestField;
- /// Property holding an integer value for testing
- public int TestProperty { get; set; }
- /// Value type field for testing
- public TestValueType ValueTypeField;
- /// Value type property for testing
- public TestValueType ValueTypeProperty { get; set; }
- /// Reference type field for testing
- public TestReferenceType ReferenceTypeField;
- /// Reference type property for testing
- public TestReferenceType ReferenceTypeProperty { get; set; }
- /// An array field of reference types
- public TestReferenceType[,][] ReferenceTypeArrayField;
- /// An array property of reference types
- public TestReferenceType[,][] ReferenceTypeArrayProperty { get; set; }
- /// A reference type field that's always null
- public TestReferenceType AlwaysNullField;
- /// A reference type property that's always null
- public TestReferenceType AlwaysNullProperty { get; set; }
- /// A property that only has a getter
- public TestReferenceType GetOnlyProperty { get { return null; } }
- /// A property that only has a setter
- public TestReferenceType SetOnlyProperty { set { } }
- /// A read-only field
- public readonly TestValueType ReadOnlyField;
- /// Field typed as base class holding a derived instance
- public TestReferenceType DerivedField;
- /// Field typed as base class holding a derived instance
- public TestReferenceType DerivedProperty { get; set; }
-
- }
-
- #endregion // struct HierarchicalValueType
-
- #region struct HierarchicalReferenceType
-
- /// A value type containiner other complex types used for testing
- protected class HierarchicalReferenceType {
-
- /// Field holding an integer value for testing
- public int TestField;
- /// Property holding an integer value for testing
- public int TestProperty { get; set; }
- /// Value type field for testing
- public TestValueType ValueTypeField;
- /// Value type property for testing
- public TestValueType ValueTypeProperty { get; set; }
- /// Reference type field for testing
- public TestReferenceType ReferenceTypeField;
- /// Reference type property for testing
- public TestReferenceType ReferenceTypeProperty { get; set; }
- /// An array field of reference types
- public TestReferenceType[,][] ReferenceTypeArrayField;
- /// An array property of reference types
- public TestReferenceType[,][] ReferenceTypeArrayProperty { get; set; }
- /// A reference type field that's always null
- public TestReferenceType AlwaysNullField;
- /// A reference type property that's always null
- public TestReferenceType AlwaysNullProperty { get; set; }
- /// A property that only has a getter
- public TestReferenceType GetOnlyProperty { get { return null; } }
- /// A property that only has a setter
- public TestReferenceType SetOnlyProperty { set { } }
- /// A read-only field
- public readonly TestValueType ReadOnlyField;
- /// Field typed as base class holding a derived instance
- public TestReferenceType DerivedField;
- /// Field typed as base class holding a derived instance
- public TestReferenceType DerivedProperty { get; set; }
-
- }
-
- #endregion // struct HierarchicalReferenceType
-
- #region class ClassWithoutDefaultConstructor
-
- /// A class that does not have a default constructor
- public class ClassWithoutDefaultConstructor {
-
- ///
- /// Initializes a new instance of the class without default constructor
- ///
- /// Dummy value that will be saved by the instance
- public ClassWithoutDefaultConstructor(int dummy) {
- this.dummy = dummy;
- }
-
- /// Dummy value that has been saved by the instance
- public int Dummy {
- get { return this.dummy; }
- }
-
- /// Dummy value that has been saved by the instance
- private int dummy;
-
- }
-
- #endregion // class ClassWithoutDefaultConstructor
-
- ///
- /// Verifies that a cloned object exhibits the expected state for the type of
- /// clone that has been performed
- ///
- /// Original instance the clone was created from
- /// Cloned instance that will be checked for correctness
- /// Whether the cloned instance is a deep clone
- ///
- /// Whether a property-based clone was performed
- ///
- protected static void VerifyClone(
- HierarchicalReferenceType original, HierarchicalReferenceType clone,
- bool isDeepClone, bool isPropertyBasedClone
- ) {
- Assert.AreNotSame(original, clone);
-
- if(isPropertyBasedClone) {
- Assert.AreEqual(0, clone.TestField);
- Assert.AreEqual(0, clone.ValueTypeField.TestField);
- Assert.AreEqual(0, clone.ValueTypeField.TestProperty);
- Assert.AreEqual(0, clone.ValueTypeProperty.TestField);
- Assert.IsNull(clone.ReferenceTypeField);
- Assert.IsNull(clone.DerivedField);
-
- if(isDeepClone) {
- Assert.AreNotSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
- Assert.AreNotSame(
- original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
- );
- Assert.AreNotSame(original.DerivedProperty, clone.DerivedProperty);
- Assert.IsInstanceOf(clone.DerivedProperty);
-
- var originalDerived = (DerivedReferenceType)original.DerivedProperty;
- var clonedDerived = (DerivedReferenceType)clone.DerivedProperty;
- Assert.AreEqual(originalDerived.TestProperty, clonedDerived.TestProperty);
- Assert.AreEqual(originalDerived.DerivedProperty, clonedDerived.DerivedProperty);
-
- Assert.AreEqual(0, clone.ReferenceTypeProperty.TestField);
- Assert.AreNotSame(
- original.ReferenceTypeArrayProperty[1, 3][0],
- clone.ReferenceTypeArrayProperty[1, 3][0]
- );
- Assert.AreNotSame(
- original.ReferenceTypeArrayProperty[1, 3][2],
- clone.ReferenceTypeArrayProperty[1, 3][2]
- );
- Assert.AreEqual(0, clone.ReferenceTypeArrayProperty[1, 3][0].TestField);
- Assert.AreEqual(0, clone.ReferenceTypeArrayProperty[1, 3][2].TestField);
- } else {
- Assert.AreSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
- Assert.AreSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
- Assert.AreSame(
- original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
- );
- }
- } else {
- Assert.AreEqual(original.TestField, clone.TestField);
- Assert.AreEqual(original.ValueTypeField.TestField, clone.ValueTypeField.TestField);
- Assert.AreEqual(original.ValueTypeField.TestProperty, clone.ValueTypeField.TestProperty);
- Assert.AreEqual(
- original.ValueTypeProperty.TestField, clone.ValueTypeProperty.TestField
- );
- Assert.AreEqual(
- original.ReferenceTypeField.TestField, clone.ReferenceTypeField.TestField
- );
- Assert.AreEqual(
- original.ReferenceTypeField.TestProperty, clone.ReferenceTypeField.TestProperty
- );
- Assert.AreEqual(
- original.ReferenceTypeProperty.TestField, clone.ReferenceTypeProperty.TestField
- );
-
- if(isDeepClone) {
- Assert.AreNotSame(original.ReferenceTypeField, clone.ReferenceTypeField);
- Assert.AreNotSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
- Assert.AreNotSame(original.DerivedField, clone.DerivedField);
- Assert.AreNotSame(original.DerivedProperty, clone.DerivedProperty);
- Assert.IsInstanceOf(clone.DerivedField);
- Assert.IsInstanceOf(clone.DerivedProperty);
-
- var originalDerived = (DerivedReferenceType)original.DerivedField;
- var clonedDerived = (DerivedReferenceType)clone.DerivedField;
- Assert.AreEqual(originalDerived.TestField, clonedDerived.TestField);
- Assert.AreEqual(originalDerived.TestProperty, clonedDerived.TestProperty);
- Assert.AreEqual(originalDerived.DerivedField, clonedDerived.DerivedField);
- Assert.AreEqual(originalDerived.DerivedProperty, clonedDerived.DerivedProperty);
-
- originalDerived = (DerivedReferenceType)original.DerivedProperty;
- clonedDerived = (DerivedReferenceType)clone.DerivedProperty;
- Assert.AreEqual(originalDerived.TestField, clonedDerived.TestField);
- Assert.AreEqual(originalDerived.TestProperty, clonedDerived.TestProperty);
- Assert.AreEqual(originalDerived.DerivedField, clonedDerived.DerivedField);
- Assert.AreEqual(originalDerived.DerivedProperty, clonedDerived.DerivedProperty);
-
- Assert.AreNotSame(
- original.ReferenceTypeArrayField, clone.ReferenceTypeArrayField
- );
- Assert.AreNotSame(
- original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
- );
- Assert.AreNotSame(
- original.ReferenceTypeArrayProperty[1, 3][0],
- clone.ReferenceTypeArrayProperty[1, 3][0]
- );
- Assert.AreNotSame(
- original.ReferenceTypeArrayProperty[1, 3][2],
- clone.ReferenceTypeArrayProperty[1, 3][2]
- );
- Assert.AreEqual(
- original.ReferenceTypeArrayProperty[1, 3][0].TestField,
- clone.ReferenceTypeArrayProperty[1, 3][0].TestField
- );
- Assert.AreEqual(
- original.ReferenceTypeArrayProperty[1, 3][2].TestField,
- clone.ReferenceTypeArrayProperty[1, 3][2].TestField
- );
- } else {
- Assert.AreSame(original.DerivedField, clone.DerivedField);
- Assert.AreSame(original.DerivedProperty, clone.DerivedProperty);
- Assert.AreSame(original.ReferenceTypeField, clone.ReferenceTypeField);
- Assert.AreSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
- Assert.AreSame(
- original.ReferenceTypeArrayField, clone.ReferenceTypeArrayField
- );
- Assert.AreSame(
- original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
- );
- }
- }
- }
-
- ///
- /// Verifies that a cloned object exhibits the expected state for the type of
- /// clone that has been performed
- ///
- /// Original instance the clone was created from
- /// Cloned instance that will be checked for correctness
- /// Whether the cloned instance is a deep clone
- ///
- /// Whether a property-based clone was performed
- ///
- protected static void VerifyClone(
- ref HierarchicalValueType original, ref HierarchicalValueType clone,
- bool isDeepClone, bool isPropertyBasedClone
- ) {
- if(isPropertyBasedClone) {
- Assert.AreEqual(0, clone.TestField);
- Assert.AreEqual(0, clone.ValueTypeField.TestField);
- Assert.AreEqual(0, clone.ValueTypeField.TestProperty);
- Assert.AreEqual(0, clone.ValueTypeProperty.TestField);
- Assert.IsNull(clone.ReferenceTypeField);
- Assert.IsNull(clone.DerivedField);
-
- if(isDeepClone) {
- Assert.AreNotSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
- Assert.AreNotSame(
- original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
- );
- Assert.AreNotSame(original.DerivedProperty, clone.DerivedProperty);
- Assert.IsInstanceOf(clone.DerivedProperty);
-
- var originalDerived = (DerivedReferenceType)original.DerivedProperty;
- var clonedDerived = (DerivedReferenceType)clone.DerivedProperty;
- Assert.AreEqual(originalDerived.TestProperty, clonedDerived.TestProperty);
- Assert.AreEqual(originalDerived.DerivedProperty, clonedDerived.DerivedProperty);
-
- Assert.AreEqual(0, clone.ReferenceTypeProperty.TestField);
- Assert.AreNotSame(
- original.ReferenceTypeArrayProperty[1, 3][0],
- clone.ReferenceTypeArrayProperty[1, 3][0]
- );
- Assert.AreNotSame(
- original.ReferenceTypeArrayProperty[1, 3][2],
- clone.ReferenceTypeArrayProperty[1, 3][2]
- );
- Assert.AreEqual(0, clone.ReferenceTypeArrayProperty[1, 3][0].TestField);
- Assert.AreEqual(0, clone.ReferenceTypeArrayProperty[1, 3][2].TestField);
- } else {
- Assert.AreSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
- Assert.AreSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
- Assert.AreSame(
- original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
- );
- }
- } else {
- Assert.AreEqual(original.TestField, clone.TestField);
- Assert.AreEqual(original.ValueTypeField.TestField, clone.ValueTypeField.TestField);
- Assert.AreEqual(original.ValueTypeField.TestProperty, clone.ValueTypeField.TestProperty);
- Assert.AreEqual(
- original.ValueTypeProperty.TestField, clone.ValueTypeProperty.TestField
- );
- Assert.AreEqual(
- original.ReferenceTypeField.TestField, clone.ReferenceTypeField.TestField
- );
- Assert.AreEqual(
- original.ReferenceTypeField.TestProperty, clone.ReferenceTypeField.TestProperty
- );
- Assert.AreEqual(
- original.ReferenceTypeProperty.TestField, clone.ReferenceTypeProperty.TestField
- );
-
- if(isDeepClone) {
- Assert.AreNotSame(original.ReferenceTypeField, clone.ReferenceTypeField);
- Assert.AreNotSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
- Assert.AreNotSame(original.DerivedField, clone.DerivedField);
- Assert.AreNotSame(original.DerivedProperty, clone.DerivedProperty);
- Assert.IsInstanceOf(clone.DerivedField);
- Assert.IsInstanceOf(clone.DerivedProperty);
-
- var originalDerived = (DerivedReferenceType)original.DerivedField;
- var clonedDerived = (DerivedReferenceType)clone.DerivedField;
- Assert.AreEqual(originalDerived.TestField, clonedDerived.TestField);
- Assert.AreEqual(originalDerived.TestProperty, clonedDerived.TestProperty);
- Assert.AreEqual(originalDerived.DerivedField, clonedDerived.DerivedField);
- Assert.AreEqual(originalDerived.DerivedProperty, clonedDerived.DerivedProperty);
-
- originalDerived = (DerivedReferenceType)original.DerivedProperty;
- clonedDerived = (DerivedReferenceType)clone.DerivedProperty;
- Assert.AreEqual(originalDerived.TestField, clonedDerived.TestField);
- Assert.AreEqual(originalDerived.TestProperty, clonedDerived.TestProperty);
- Assert.AreEqual(originalDerived.DerivedField, clonedDerived.DerivedField);
- Assert.AreEqual(originalDerived.DerivedProperty, clonedDerived.DerivedProperty);
-
- Assert.AreNotSame(
- original.ReferenceTypeArrayField, clone.ReferenceTypeArrayField
- );
- Assert.AreNotSame(
- original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
- );
- Assert.AreNotSame(
- original.ReferenceTypeArrayProperty[1, 3][0],
- clone.ReferenceTypeArrayProperty[1, 3][0]
- );
- Assert.AreNotSame(
- original.ReferenceTypeArrayProperty[1, 3][2],
- clone.ReferenceTypeArrayProperty[1, 3][2]
- );
- Assert.AreEqual(
- original.ReferenceTypeArrayProperty[1, 3][0].TestField,
- clone.ReferenceTypeArrayProperty[1, 3][0].TestField
- );
- Assert.AreEqual(
- original.ReferenceTypeArrayProperty[1, 3][2].TestField,
- clone.ReferenceTypeArrayProperty[1, 3][2].TestField
- );
- } else {
- Assert.AreSame(original.DerivedField, clone.DerivedField);
- Assert.AreSame(original.DerivedProperty, clone.DerivedProperty);
- Assert.AreSame(original.ReferenceTypeField, clone.ReferenceTypeField);
- Assert.AreSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
- Assert.AreSame(
- original.ReferenceTypeArrayField, clone.ReferenceTypeArrayField
- );
- Assert.AreSame(
- original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
- );
- }
- }
-
- Assert.AreEqual(original.TestProperty, clone.TestProperty);
- Assert.AreEqual(
- original.ValueTypeProperty.TestProperty, clone.ValueTypeProperty.TestProperty
- );
- Assert.AreEqual(
- original.ReferenceTypeProperty.TestProperty, clone.ReferenceTypeProperty.TestProperty
- );
- Assert.AreEqual(
- original.ReferenceTypeArrayProperty[1, 3][0].TestProperty,
- clone.ReferenceTypeArrayProperty[1, 3][0].TestProperty
- );
- Assert.AreEqual(
- original.ReferenceTypeArrayProperty[1, 3][2].TestProperty,
- clone.ReferenceTypeArrayProperty[1, 3][2].TestProperty
- );
- }
-
- /// Creates a value type with random data for testing
- /// A new value type with random data
- protected static HierarchicalValueType CreateValueType() {
- return new HierarchicalValueType() {
- TestField = 123,
- TestProperty = 321,
- ReferenceTypeArrayField = new TestReferenceType[2, 4][] {
- {
- null, null, null, null
- },
- {
- null, null, null,
- new TestReferenceType[3] {
- new TestReferenceType() { TestField = 101, TestProperty = 202 },
- null,
- new TestReferenceType() { TestField = 909, TestProperty = 808 }
- }
- },
- },
- ReferenceTypeArrayProperty = new TestReferenceType[2, 4][] {
- {
- null, null, null, null
- },
- {
- null, null, null,
- new TestReferenceType[3] {
- new TestReferenceType() { TestField = 303, TestProperty = 404 },
- null,
- new TestReferenceType() { TestField = 707, TestProperty = 606 }
- }
- },
- },
- ValueTypeField = new TestValueType() {
- TestField = 456,
- TestProperty = 654
- },
- ValueTypeProperty = new TestValueType() {
- TestField = 789,
- TestProperty = 987,
- },
- ReferenceTypeField = new TestReferenceType() {
- TestField = 135,
- TestProperty = 531
- },
- ReferenceTypeProperty = new TestReferenceType() {
- TestField = 246,
- TestProperty = 642,
- },
- DerivedField = new DerivedReferenceType() {
- DerivedField = 100,
- DerivedProperty = 200,
- TestField = 300,
- TestProperty = 400
- },
- DerivedProperty = new DerivedReferenceType() {
- DerivedField = 500,
- DerivedProperty = 600,
- TestField = 700,
- TestProperty = 800
- }
- };
- }
-
- /// Creates a reference type with random data for testing
- /// A new reference type with random data
- protected static HierarchicalReferenceType CreateReferenceType() {
- return new HierarchicalReferenceType() {
- TestField = 123,
- TestProperty = 321,
- ReferenceTypeArrayField = new TestReferenceType[2, 4][] {
- {
- null, null, null, null
- },
- {
- null, null, null,
- new TestReferenceType[3] {
- new TestReferenceType() { TestField = 101, TestProperty = 202 },
- null,
- new TestReferenceType() { TestField = 909, TestProperty = 808 }
- }
- },
- },
- ReferenceTypeArrayProperty = new TestReferenceType[2, 4][] {
- {
- null, null, null, null
- },
- {
- null, null, null,
- new TestReferenceType[3] {
- new TestReferenceType() { TestField = 303, TestProperty = 404 },
- null,
- new TestReferenceType() { TestField = 707, TestProperty = 606 }
- }
- },
- },
- ValueTypeField = new TestValueType() {
- TestField = 456,
- TestProperty = 654
- },
- ValueTypeProperty = new TestValueType() {
- TestField = 789,
- TestProperty = 987,
- },
- ReferenceTypeField = new TestReferenceType() {
- TestField = 135,
- TestProperty = 531
- },
- ReferenceTypeProperty = new TestReferenceType() {
- TestField = 246,
- TestProperty = 642,
- },
- DerivedField = new DerivedReferenceType() {
- DerivedField = 100,
- DerivedProperty = 200,
- TestField = 300,
- TestProperty = 400
- },
- DerivedProperty = new DerivedReferenceType() {
- DerivedField = 500,
- DerivedProperty = 600,
- TestField = 700,
- TestProperty = 800
- }
- };
- }
-
- ///
- /// Useless method that avoids a compile warnings due to unused fields
- ///
- protected void AvoidCompilerWarnings() {
- var reference = new HierarchicalReferenceType() {
- AlwaysNullField = new TestReferenceType()
- };
- var value = new HierarchicalValueType() {
- AlwaysNullField = new TestReferenceType()
- };
- }
-
- }
-
-} // namespace Nuclex.Support.Cloning
-
-#endif // UNITTEST
+#region Apache License 2.0
+/*
+Nuclex .NET Framework
+Copyright (C) 2002-2024 Markus Ewald / Nuclex Development Labs
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#endregion // Apache License 2.0
+
+#if UNITTEST
+
+using System;
+
+using NUnit.Framework;
+
+namespace Nuclex.Support.Cloning {
+
+ /// Base class for unit tests verifying the clone factory
+ internal abstract class CloneFactoryTest {
+
+ #region class DerivedReferenceType
+
+ /// A derived reference type being used for testing
+ protected class DerivedReferenceType : TestReferenceType {
+
+ /// Field holding an integer value for testing
+ public int DerivedField;
+ /// Property holding an integer value for testing
+ public int DerivedProperty { get; set; }
+
+ }
+
+ #endregion // class DerivedReferenceType
+
+ #region class TestReferenceType
+
+ /// A reference type being used for testing
+ protected class TestReferenceType {
+
+ /// Field holding an integer value for testing
+ public int TestField;
+ /// Property holding an integer value for testing
+ public int TestProperty { get; set; }
+
+ }
+
+ #endregion // class TestReferenceType
+
+ #region struct TestValueType
+
+ /// A value type being used for testing
+ protected struct TestValueType {
+
+ /// Field holding an integer value for testing
+ public int TestField;
+ /// Property holding an integer value for testing
+ public int TestProperty { get; set; }
+
+ }
+
+ #endregion // struct TestValueType
+
+ #region struct HierarchicalValueType
+
+ /// A value type containiner other complex types used for testing
+ protected struct HierarchicalValueType {
+
+ /// Field holding an integer value for testing
+ public int TestField;
+ /// Property holding an integer value for testing
+ public int TestProperty { get; set; }
+ /// Value type field for testing
+ public TestValueType ValueTypeField;
+ /// Value type property for testing
+ public TestValueType ValueTypeProperty { get; set; }
+ /// Reference type field for testing
+ public TestReferenceType ReferenceTypeField;
+ /// Reference type property for testing
+ public TestReferenceType ReferenceTypeProperty { get; set; }
+ /// An array field of reference types
+ public TestReferenceType[,][] ReferenceTypeArrayField;
+ /// An array property of reference types
+ public TestReferenceType[,][] ReferenceTypeArrayProperty { get; set; }
+ /// A reference type field that's always null
+ public TestReferenceType AlwaysNullField;
+ /// A reference type property that's always null
+ public TestReferenceType AlwaysNullProperty { get; set; }
+ /// A property that only has a getter
+ public TestReferenceType GetOnlyProperty { get { return null; } }
+ /// A property that only has a setter
+ public TestReferenceType SetOnlyProperty { set { } }
+ /// A read-only field
+ public readonly TestValueType ReadOnlyField;
+ /// Field typed as base class holding a derived instance
+ public TestReferenceType DerivedField;
+ /// Field typed as base class holding a derived instance
+ public TestReferenceType DerivedProperty { get; set; }
+
+ }
+
+ #endregion // struct HierarchicalValueType
+
+ #region struct HierarchicalReferenceType
+
+ /// A value type containiner other complex types used for testing
+ protected class HierarchicalReferenceType {
+
+ /// Field holding an integer value for testing
+ public int TestField;
+ /// Property holding an integer value for testing
+ public int TestProperty { get; set; }
+ /// Value type field for testing
+ public TestValueType ValueTypeField;
+ /// Value type property for testing
+ public TestValueType ValueTypeProperty { get; set; }
+ /// Reference type field for testing
+ public TestReferenceType ReferenceTypeField;
+ /// Reference type property for testing
+ public TestReferenceType ReferenceTypeProperty { get; set; }
+ /// An array field of reference types
+ public TestReferenceType[,][] ReferenceTypeArrayField;
+ /// An array property of reference types
+ public TestReferenceType[,][] ReferenceTypeArrayProperty { get; set; }
+ /// A reference type field that's always null
+ public TestReferenceType AlwaysNullField;
+ /// A reference type property that's always null
+ public TestReferenceType AlwaysNullProperty { get; set; }
+ /// A property that only has a getter
+ public TestReferenceType GetOnlyProperty { get { return null; } }
+ /// A property that only has a setter
+ public TestReferenceType SetOnlyProperty { set { } }
+ /// A read-only field
+ public readonly TestValueType ReadOnlyField;
+ /// Field typed as base class holding a derived instance
+ public TestReferenceType DerivedField;
+ /// Field typed as base class holding a derived instance
+ public TestReferenceType DerivedProperty { get; set; }
+
+ }
+
+ #endregion // struct HierarchicalReferenceType
+
+ #region class ClassWithoutDefaultConstructor
+
+ /// A class that does not have a default constructor
+ public class ClassWithoutDefaultConstructor {
+
+ ///
+ /// Initializes a new instance of the class without default constructor
+ ///
+ /// Dummy value that will be saved by the instance
+ public ClassWithoutDefaultConstructor(int dummy) {
+ this.dummy = dummy;
+ }
+
+ /// Dummy value that has been saved by the instance
+ public int Dummy {
+ get { return this.dummy; }
+ }
+
+ /// Dummy value that has been saved by the instance
+ private int dummy;
+
+ }
+
+ #endregion // class ClassWithoutDefaultConstructor
+
+ ///
+ /// Verifies that a cloned object exhibits the expected state for the type of
+ /// clone that has been performed
+ ///
+ /// Original instance the clone was created from
+ /// Cloned instance that will be checked for correctness
+ /// Whether the cloned instance is a deep clone
+ ///
+ /// Whether a property-based clone was performed
+ ///
+ protected static void VerifyClone(
+ HierarchicalReferenceType original, HierarchicalReferenceType clone,
+ bool isDeepClone, bool isPropertyBasedClone
+ ) {
+ Assert.AreNotSame(original, clone);
+
+ if(isPropertyBasedClone) {
+ Assert.AreEqual(0, clone.TestField);
+ Assert.AreEqual(0, clone.ValueTypeField.TestField);
+ Assert.AreEqual(0, clone.ValueTypeField.TestProperty);
+ Assert.AreEqual(0, clone.ValueTypeProperty.TestField);
+ Assert.IsNull(clone.ReferenceTypeField);
+ Assert.IsNull(clone.DerivedField);
+
+ if(isDeepClone) {
+ Assert.AreNotSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
+ Assert.AreNotSame(
+ original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
+ );
+ Assert.AreNotSame(original.DerivedProperty, clone.DerivedProperty);
+ Assert.IsInstanceOf(clone.DerivedProperty);
+
+ var originalDerived = (DerivedReferenceType)original.DerivedProperty;
+ var clonedDerived = (DerivedReferenceType)clone.DerivedProperty;
+ Assert.AreEqual(originalDerived.TestProperty, clonedDerived.TestProperty);
+ Assert.AreEqual(originalDerived.DerivedProperty, clonedDerived.DerivedProperty);
+
+ Assert.AreEqual(0, clone.ReferenceTypeProperty.TestField);
+ Assert.AreNotSame(
+ original.ReferenceTypeArrayProperty[1, 3][0],
+ clone.ReferenceTypeArrayProperty[1, 3][0]
+ );
+ Assert.AreNotSame(
+ original.ReferenceTypeArrayProperty[1, 3][2],
+ clone.ReferenceTypeArrayProperty[1, 3][2]
+ );
+ Assert.AreEqual(0, clone.ReferenceTypeArrayProperty[1, 3][0].TestField);
+ Assert.AreEqual(0, clone.ReferenceTypeArrayProperty[1, 3][2].TestField);
+ } else {
+ Assert.AreSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
+ Assert.AreSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
+ Assert.AreSame(
+ original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
+ );
+ }
+ } else {
+ Assert.AreEqual(original.TestField, clone.TestField);
+ Assert.AreEqual(original.ValueTypeField.TestField, clone.ValueTypeField.TestField);
+ Assert.AreEqual(original.ValueTypeField.TestProperty, clone.ValueTypeField.TestProperty);
+ Assert.AreEqual(
+ original.ValueTypeProperty.TestField, clone.ValueTypeProperty.TestField
+ );
+ Assert.AreEqual(
+ original.ReferenceTypeField.TestField, clone.ReferenceTypeField.TestField
+ );
+ Assert.AreEqual(
+ original.ReferenceTypeField.TestProperty, clone.ReferenceTypeField.TestProperty
+ );
+ Assert.AreEqual(
+ original.ReferenceTypeProperty.TestField, clone.ReferenceTypeProperty.TestField
+ );
+
+ if(isDeepClone) {
+ Assert.AreNotSame(original.ReferenceTypeField, clone.ReferenceTypeField);
+ Assert.AreNotSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
+ Assert.AreNotSame(original.DerivedField, clone.DerivedField);
+ Assert.AreNotSame(original.DerivedProperty, clone.DerivedProperty);
+ Assert.IsInstanceOf(clone.DerivedField);
+ Assert.IsInstanceOf(clone.DerivedProperty);
+
+ var originalDerived = (DerivedReferenceType)original.DerivedField;
+ var clonedDerived = (DerivedReferenceType)clone.DerivedField;
+ Assert.AreEqual(originalDerived.TestField, clonedDerived.TestField);
+ Assert.AreEqual(originalDerived.TestProperty, clonedDerived.TestProperty);
+ Assert.AreEqual(originalDerived.DerivedField, clonedDerived.DerivedField);
+ Assert.AreEqual(originalDerived.DerivedProperty, clonedDerived.DerivedProperty);
+
+ originalDerived = (DerivedReferenceType)original.DerivedProperty;
+ clonedDerived = (DerivedReferenceType)clone.DerivedProperty;
+ Assert.AreEqual(originalDerived.TestField, clonedDerived.TestField);
+ Assert.AreEqual(originalDerived.TestProperty, clonedDerived.TestProperty);
+ Assert.AreEqual(originalDerived.DerivedField, clonedDerived.DerivedField);
+ Assert.AreEqual(originalDerived.DerivedProperty, clonedDerived.DerivedProperty);
+
+ Assert.AreNotSame(
+ original.ReferenceTypeArrayField, clone.ReferenceTypeArrayField
+ );
+ Assert.AreNotSame(
+ original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
+ );
+ Assert.AreNotSame(
+ original.ReferenceTypeArrayProperty[1, 3][0],
+ clone.ReferenceTypeArrayProperty[1, 3][0]
+ );
+ Assert.AreNotSame(
+ original.ReferenceTypeArrayProperty[1, 3][2],
+ clone.ReferenceTypeArrayProperty[1, 3][2]
+ );
+ Assert.AreEqual(
+ original.ReferenceTypeArrayProperty[1, 3][0].TestField,
+ clone.ReferenceTypeArrayProperty[1, 3][0].TestField
+ );
+ Assert.AreEqual(
+ original.ReferenceTypeArrayProperty[1, 3][2].TestField,
+ clone.ReferenceTypeArrayProperty[1, 3][2].TestField
+ );
+ } else {
+ Assert.AreSame(original.DerivedField, clone.DerivedField);
+ Assert.AreSame(original.DerivedProperty, clone.DerivedProperty);
+ Assert.AreSame(original.ReferenceTypeField, clone.ReferenceTypeField);
+ Assert.AreSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
+ Assert.AreSame(
+ original.ReferenceTypeArrayField, clone.ReferenceTypeArrayField
+ );
+ Assert.AreSame(
+ original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
+ );
+ }
+ }
+ }
+
+ ///
+ /// Verifies that a cloned object exhibits the expected state for the type of
+ /// clone that has been performed
+ ///
+ /// Original instance the clone was created from
+ /// Cloned instance that will be checked for correctness
+ /// Whether the cloned instance is a deep clone
+ ///
+ /// Whether a property-based clone was performed
+ ///
+ protected static void VerifyClone(
+ ref HierarchicalValueType original, ref HierarchicalValueType clone,
+ bool isDeepClone, bool isPropertyBasedClone
+ ) {
+ if(isPropertyBasedClone) {
+ Assert.AreEqual(0, clone.TestField);
+ Assert.AreEqual(0, clone.ValueTypeField.TestField);
+ Assert.AreEqual(0, clone.ValueTypeField.TestProperty);
+ Assert.AreEqual(0, clone.ValueTypeProperty.TestField);
+ Assert.IsNull(clone.ReferenceTypeField);
+ Assert.IsNull(clone.DerivedField);
+
+ if(isDeepClone) {
+ Assert.AreNotSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
+ Assert.AreNotSame(
+ original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
+ );
+ Assert.AreNotSame(original.DerivedProperty, clone.DerivedProperty);
+ Assert.IsInstanceOf(clone.DerivedProperty);
+
+ var originalDerived = (DerivedReferenceType)original.DerivedProperty;
+ var clonedDerived = (DerivedReferenceType)clone.DerivedProperty;
+ Assert.AreEqual(originalDerived.TestProperty, clonedDerived.TestProperty);
+ Assert.AreEqual(originalDerived.DerivedProperty, clonedDerived.DerivedProperty);
+
+ Assert.AreEqual(0, clone.ReferenceTypeProperty.TestField);
+ Assert.AreNotSame(
+ original.ReferenceTypeArrayProperty[1, 3][0],
+ clone.ReferenceTypeArrayProperty[1, 3][0]
+ );
+ Assert.AreNotSame(
+ original.ReferenceTypeArrayProperty[1, 3][2],
+ clone.ReferenceTypeArrayProperty[1, 3][2]
+ );
+ Assert.AreEqual(0, clone.ReferenceTypeArrayProperty[1, 3][0].TestField);
+ Assert.AreEqual(0, clone.ReferenceTypeArrayProperty[1, 3][2].TestField);
+ } else {
+ Assert.AreSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
+ Assert.AreSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
+ Assert.AreSame(
+ original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
+ );
+ }
+ } else {
+ Assert.AreEqual(original.TestField, clone.TestField);
+ Assert.AreEqual(original.ValueTypeField.TestField, clone.ValueTypeField.TestField);
+ Assert.AreEqual(original.ValueTypeField.TestProperty, clone.ValueTypeField.TestProperty);
+ Assert.AreEqual(
+ original.ValueTypeProperty.TestField, clone.ValueTypeProperty.TestField
+ );
+ Assert.AreEqual(
+ original.ReferenceTypeField.TestField, clone.ReferenceTypeField.TestField
+ );
+ Assert.AreEqual(
+ original.ReferenceTypeField.TestProperty, clone.ReferenceTypeField.TestProperty
+ );
+ Assert.AreEqual(
+ original.ReferenceTypeProperty.TestField, clone.ReferenceTypeProperty.TestField
+ );
+
+ if(isDeepClone) {
+ Assert.AreNotSame(original.ReferenceTypeField, clone.ReferenceTypeField);
+ Assert.AreNotSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
+ Assert.AreNotSame(original.DerivedField, clone.DerivedField);
+ Assert.AreNotSame(original.DerivedProperty, clone.DerivedProperty);
+ Assert.IsInstanceOf(clone.DerivedField);
+ Assert.IsInstanceOf(clone.DerivedProperty);
+
+ var originalDerived = (DerivedReferenceType)original.DerivedField;
+ var clonedDerived = (DerivedReferenceType)clone.DerivedField;
+ Assert.AreEqual(originalDerived.TestField, clonedDerived.TestField);
+ Assert.AreEqual(originalDerived.TestProperty, clonedDerived.TestProperty);
+ Assert.AreEqual(originalDerived.DerivedField, clonedDerived.DerivedField);
+ Assert.AreEqual(originalDerived.DerivedProperty, clonedDerived.DerivedProperty);
+
+ originalDerived = (DerivedReferenceType)original.DerivedProperty;
+ clonedDerived = (DerivedReferenceType)clone.DerivedProperty;
+ Assert.AreEqual(originalDerived.TestField, clonedDerived.TestField);
+ Assert.AreEqual(originalDerived.TestProperty, clonedDerived.TestProperty);
+ Assert.AreEqual(originalDerived.DerivedField, clonedDerived.DerivedField);
+ Assert.AreEqual(originalDerived.DerivedProperty, clonedDerived.DerivedProperty);
+
+ Assert.AreNotSame(
+ original.ReferenceTypeArrayField, clone.ReferenceTypeArrayField
+ );
+ Assert.AreNotSame(
+ original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
+ );
+ Assert.AreNotSame(
+ original.ReferenceTypeArrayProperty[1, 3][0],
+ clone.ReferenceTypeArrayProperty[1, 3][0]
+ );
+ Assert.AreNotSame(
+ original.ReferenceTypeArrayProperty[1, 3][2],
+ clone.ReferenceTypeArrayProperty[1, 3][2]
+ );
+ Assert.AreEqual(
+ original.ReferenceTypeArrayProperty[1, 3][0].TestField,
+ clone.ReferenceTypeArrayProperty[1, 3][0].TestField
+ );
+ Assert.AreEqual(
+ original.ReferenceTypeArrayProperty[1, 3][2].TestField,
+ clone.ReferenceTypeArrayProperty[1, 3][2].TestField
+ );
+ } else {
+ Assert.AreSame(original.DerivedField, clone.DerivedField);
+ Assert.AreSame(original.DerivedProperty, clone.DerivedProperty);
+ Assert.AreSame(original.ReferenceTypeField, clone.ReferenceTypeField);
+ Assert.AreSame(original.ReferenceTypeProperty, clone.ReferenceTypeProperty);
+ Assert.AreSame(
+ original.ReferenceTypeArrayField, clone.ReferenceTypeArrayField
+ );
+ Assert.AreSame(
+ original.ReferenceTypeArrayProperty, clone.ReferenceTypeArrayProperty
+ );
+ }
+ }
+
+ Assert.AreEqual(original.TestProperty, clone.TestProperty);
+ Assert.AreEqual(
+ original.ValueTypeProperty.TestProperty, clone.ValueTypeProperty.TestProperty
+ );
+ Assert.AreEqual(
+ original.ReferenceTypeProperty.TestProperty, clone.ReferenceTypeProperty.TestProperty
+ );
+ Assert.AreEqual(
+ original.ReferenceTypeArrayProperty[1, 3][0].TestProperty,
+ clone.ReferenceTypeArrayProperty[1, 3][0].TestProperty
+ );
+ Assert.AreEqual(
+ original.ReferenceTypeArrayProperty[1, 3][2].TestProperty,
+ clone.ReferenceTypeArrayProperty[1, 3][2].TestProperty
+ );
+ }
+
+ /// Creates a value type with random data for testing
+ /// A new value type with random data
+ protected static HierarchicalValueType CreateValueType() {
+ return new HierarchicalValueType() {
+ TestField = 123,
+ TestProperty = 321,
+ ReferenceTypeArrayField = new TestReferenceType[2, 4][] {
+ {
+ null, null, null, null
+ },
+ {
+ null, null, null,
+ new TestReferenceType[3] {
+ new TestReferenceType() { TestField = 101, TestProperty = 202 },
+ null,
+ new TestReferenceType() { TestField = 909, TestProperty = 808 }
+ }
+ },
+ },
+ ReferenceTypeArrayProperty = new TestReferenceType[2, 4][] {
+ {
+ null, null, null, null
+ },
+ {
+ null, null, null,
+ new TestReferenceType[3] {
+ new TestReferenceType() { TestField = 303, TestProperty = 404 },
+ null,
+ new TestReferenceType() { TestField = 707, TestProperty = 606 }
+ }
+ },
+ },
+ ValueTypeField = new TestValueType() {
+ TestField = 456,
+ TestProperty = 654
+ },
+ ValueTypeProperty = new TestValueType() {
+ TestField = 789,
+ TestProperty = 987,
+ },
+ ReferenceTypeField = new TestReferenceType() {
+ TestField = 135,
+ TestProperty = 531
+ },
+ ReferenceTypeProperty = new TestReferenceType() {
+ TestField = 246,
+ TestProperty = 642,
+ },
+ DerivedField = new DerivedReferenceType() {
+ DerivedField = 100,
+ DerivedProperty = 200,
+ TestField = 300,
+ TestProperty = 400
+ },
+ DerivedProperty = new DerivedReferenceType() {
+ DerivedField = 500,
+ DerivedProperty = 600,
+ TestField = 700,
+ TestProperty = 800
+ }
+ };
+ }
+
+ /// Creates a reference type with random data for testing
+ /// A new reference type with random data
+ protected static HierarchicalReferenceType CreateReferenceType() {
+ return new HierarchicalReferenceType() {
+ TestField = 123,
+ TestProperty = 321,
+ ReferenceTypeArrayField = new TestReferenceType[2, 4][] {
+ {
+ null, null, null, null
+ },
+ {
+ null, null, null,
+ new TestReferenceType[3] {
+ new TestReferenceType() { TestField = 101, TestProperty = 202 },
+ null,
+ new TestReferenceType() { TestField = 909, TestProperty = 808 }
+ }
+ },
+ },
+ ReferenceTypeArrayProperty = new TestReferenceType[2, 4][] {
+ {
+ null, null, null, null
+ },
+ {
+ null, null, null,
+ new TestReferenceType[3] {
+ new TestReferenceType() { TestField = 303, TestProperty = 404 },
+ null,
+ new TestReferenceType() { TestField = 707, TestProperty = 606 }
+ }
+ },
+ },
+ ValueTypeField = new TestValueType() {
+ TestField = 456,
+ TestProperty = 654
+ },
+ ValueTypeProperty = new TestValueType() {
+ TestField = 789,
+ TestProperty = 987,
+ },
+ ReferenceTypeField = new TestReferenceType() {
+ TestField = 135,
+ TestProperty = 531
+ },
+ ReferenceTypeProperty = new TestReferenceType() {
+ TestField = 246,
+ TestProperty = 642,
+ },
+ DerivedField = new DerivedReferenceType() {
+ DerivedField = 100,
+ DerivedProperty = 200,
+ TestField = 300,
+ TestProperty = 400
+ },
+ DerivedProperty = new DerivedReferenceType() {
+ DerivedField = 500,
+ DerivedProperty = 600,
+ TestField = 700,
+ TestProperty = 800
+ }
+ };
+ }
+
+ ///
+ /// Useless method that avoids a compile warnings due to unused fields
+ ///
+ protected void AvoidCompilerWarnings() {
+ var reference = new HierarchicalReferenceType() {
+ AlwaysNullField = new TestReferenceType()
+ };
+ var value = new HierarchicalValueType() {
+ AlwaysNullField = new TestReferenceType()
+ };
+ }
+
+ }
+
+} // namespace Nuclex.Support.Cloning
+
+#endif // UNITTEST
diff --git a/Source/Cloning/ExpressionTreeCloner.FieldBased.cs b/Source/Cloning/ExpressionTreeCloner.FieldBased.cs
index 31a34eb..0b5405b 100644
--- a/Source/Cloning/ExpressionTreeCloner.FieldBased.cs
+++ b/Source/Cloning/ExpressionTreeCloner.FieldBased.cs
@@ -1,680 +1,679 @@
-#region CPL License
-/*
-Nuclex Framework
-Copyright (C) 2002-2017 Nuclex Development Labs
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the IBM Common Public License as
-published by the IBM Corporation; either version 1.0 of the
-License, or (at your option) any later version.
-
-This library 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
-IBM Common Public License for more details.
-
-You should have received a copy of the IBM Common Public
-License along with this library
-*/
-#endregion
-
-#if !NO_SETS
-
-using System;
-using System.Collections.Generic;
-using System.Linq.Expressions;
-using System.Reflection;
-using System.Runtime.Serialization;
-
-namespace Nuclex.Support.Cloning {
-
- partial class ExpressionTreeCloner : ICloneFactory {
-
- /// Compiles a method that creates a deep clone of an object
- /// Type for which a clone method will be created
- /// A method that clones an object of the provided type
- ///
- ///
- /// The 'null' check is supposed to take place before running the cloner. This
- /// avoids having redundant 'null' checks on nested types - first before calling
- /// GetType() on the field to be cloned and second when runner the matching
- /// cloner for the field.
- ///
- ///
- /// This design also enables the cloning of nested value types (which can never
- /// be null) without any null check whatsoever.
- ///
- ///
- private static Func