diff --git a/Source/Cloning/ExpressionTreeCloner.Test.cs b/Source/Cloning/ExpressionTreeCloner.Test.cs
index 8f782f3..9107a72 100644
--- a/Source/Cloning/ExpressionTreeCloner.Test.cs
+++ b/Source/Cloning/ExpressionTreeCloner.Test.cs
@@ -77,6 +77,7 @@ namespace Nuclex.Support.Cloning {
Assert.AreSame(original[0], clone[0]);
}
#endif
+
/// Verifies that deep clones of arrays can be made
[Test]
public void DeepClonesOfArraysCanBeMade() {
@@ -87,11 +88,11 @@ namespace Nuclex.Support.Cloning {
};
TestReferenceType[,] clone = this.cloneFactory.DeepClone(original, false);
- //Assert.AreNotSame(original[0, 0], clone[0, 0]);
- //Assert.AreEqual(original[0,0].TestField, clone[0,0].TestField);
- //Assert.AreEqual(original[0,0].TestProperty, clone[0,0].TestProperty);
+ Assert.AreNotSame(original[0, 0], clone[0, 0]);
+ Assert.AreEqual(original[0, 0].TestField, clone[0, 0].TestField);
+ Assert.AreEqual(original[0, 0].TestProperty, clone[0, 0].TestProperty);
}
-#if false
+
/// Verifies that deep clones of a generic list can be made
[Test]
public void GenericListsCanBeCloned() {
@@ -111,6 +112,7 @@ namespace Nuclex.Support.Cloning {
Assert.AreEqual("one", clone[1]);
}
+#if false
///
/// Verifies that a field-based shallow clone of a value type can be performed
///
@@ -138,7 +140,7 @@ namespace Nuclex.Support.Cloning {
public void DeepFieldBasedClonesOfValueTypesCanBeMade() {
HierarchicalValueType original = CreateValueType();
HierarchicalValueType clone = this.cloneFactory.DeepClone(original, false);
- //VerifyClone(ref original, ref clone, isDeepClone: true, isPropertyBasedClone: false);
+ VerifyClone(ref original, ref clone, isDeepClone: true, isPropertyBasedClone: false);
}
///
@@ -148,7 +150,7 @@ namespace Nuclex.Support.Cloning {
public void DeepFieldBasedClonesOfReferenceTypesCanBeMade() {
HierarchicalReferenceType original = CreateReferenceType();
HierarchicalReferenceType clone = this.cloneFactory.DeepClone(original, false);
- //VerifyClone(original, clone, isDeepClone: true, isPropertyBasedClone: false);
+ VerifyClone(original, clone, isDeepClone: true, isPropertyBasedClone: false);
}
#if false
@@ -171,7 +173,9 @@ namespace Nuclex.Support.Cloning {
HierarchicalReferenceType clone = this.cloneFactory.ShallowClone(original, true);
VerifyClone(original, clone, isDeepClone: false, isPropertyBasedClone: true);
}
+#endif
+#if false
///
/// Verifies that a property-based deep clone of a value type can be performed
///
diff --git a/Source/Cloning/ExpressionTreeCloner.cs b/Source/Cloning/ExpressionTreeCloner.cs
index 158e7b1..7c960f4 100644
--- a/Source/Cloning/ExpressionTreeCloner.cs
+++ b/Source/Cloning/ExpressionTreeCloner.cs
@@ -285,23 +285,35 @@ namespace Nuclex.Support.Cloning {
Expression.Assign(Expression.ArrayAccess(clone, indexes), clonedElement)
);
} else {
- ParameterExpression clonedElement = Expression.Variable(elementType);
- loopVariables.Add(clonedElement);
-
- nestedTransferExpressions.Add(
- Expression.Assign(clonedElement, originalElement)
+ // Complex types are cloned by checking their actual, concrete type (fields
+ // may be typed to an interface or base class) and requesting a cloner for that
+ // type during runtime
+ MethodInfo getOrCreateClonerMethodInfo = typeof(ExpressionTreeCloner).GetMethod(
+ "getOrCreateDeepFieldBasedCloner",
+ BindingFlags.NonPublic | BindingFlags.Static
);
+ MethodInfo getTypeMethodInfo = typeof(object).GetMethod("GetType");
+ MethodInfo invokeMethodInfo = typeof(Func