public void CloneSByte()
        {
            Assert.IsTrue(Cloneable <SByte> .CanClone());
            Assert.IsTrue(Cloneable <SByte> .CanShallowClone());
            Assert.IsTrue(Cloneable <SByte?> .CanClone());
            Assert.IsTrue(Cloneable <SByte?> .CanShallowClone());

            Assert.AreEqual((SByte)(-8), Cloneable <SByte> .Clone(-8));
            Assert.AreEqual((SByte)(-8), Cloneable <SByte> .ShallowClone(-8));

            Assert.AreEqual((SByte?)(-8), Cloneable <SByte?> .Clone(-8));
            Assert.AreEqual((SByte?)(-8), Cloneable <SByte?> .ShallowClone(-8));
            Assert.AreEqual((SByte?)(null), Cloneable <SByte?> .Clone(null));
            Assert.AreEqual((SByte?)(null), Cloneable <SByte?> .ShallowClone(null));
        }
        public void CloneBoolean()
        {
            Assert.IsTrue(Cloneable <Boolean> .CanClone());
            Assert.IsTrue(Cloneable <Boolean> .CanShallowClone());
            Assert.IsTrue(Cloneable <Boolean?> .CanClone());
            Assert.IsTrue(Cloneable <Boolean?> .CanShallowClone());

            Assert.AreEqual(true, Cloneable <Boolean> .Clone(true));
            Assert.AreEqual(true, Cloneable <Boolean> .ShallowClone(true));

            Assert.AreEqual(true, Cloneable <Boolean?> .Clone(true));
            Assert.AreEqual(true, Cloneable <Boolean?> .ShallowClone(true));
            Assert.AreEqual(null, Cloneable <Boolean?> .Clone(null));
            Assert.AreEqual(null, Cloneable <Boolean?> .ShallowClone(null));
        }
        public void CloneUInt64()
        {
            Assert.IsTrue(Cloneable <UInt64> .CanClone());
            Assert.IsTrue(Cloneable <UInt64> .CanShallowClone());
            Assert.IsTrue(Cloneable <UInt64?> .CanClone());
            Assert.IsTrue(Cloneable <UInt64?> .CanShallowClone());

            Assert.AreEqual((UInt64)64, Cloneable <UInt64> .Clone(64));
            Assert.AreEqual((UInt64)64, Cloneable <UInt64> .ShallowClone(64));

            Assert.AreEqual((UInt64?)64, Cloneable <UInt64?> .Clone(64));
            Assert.AreEqual((UInt64?)64, Cloneable <UInt64?> .ShallowClone(64));
            Assert.AreEqual((UInt64?)null, Cloneable <UInt64?> .Clone(null));
            Assert.AreEqual((UInt64?)null, Cloneable <UInt64?> .ShallowClone(null));
        }
        public void CloneInt32()
        {
            Assert.IsTrue(Cloneable <Int32> .CanClone());
            Assert.IsTrue(Cloneable <Int32> .CanShallowClone());
            Assert.IsTrue(Cloneable <Int32?> .CanClone());
            Assert.IsTrue(Cloneable <Int32?> .CanShallowClone());

            Assert.AreEqual((Int32)(-32), Cloneable <Int32> .Clone(-32));
            Assert.AreEqual((Int32)(-32), Cloneable <Int32> .ShallowClone(-32));

            Assert.AreEqual((Int32?)(-32), Cloneable <Int32?> .Clone(-32));
            Assert.AreEqual((Int32?)(-32), Cloneable <Int32?> .ShallowClone(-32));
            Assert.AreEqual((Int32?)(null), Cloneable <Int32?> .Clone(null));
            Assert.AreEqual((Int32?)(null), Cloneable <Int32?> .ShallowClone(null));
        }
        public void CloneToClassArray()
        {
            var destinationClass = new CloneTestClass();

            var source = new[] { new CloneTestClass {
                                     FirstName = "John", LastName = "Doe"
                                 } };
            var destination = new[] { destinationClass };

            Cloneable <CloneTestClass[]> .CloneTo(source, destination);

            Assert.IsTrue(ReferenceEquals(destinationClass, destination[0]));
            Assert.AreEqual("John", destinationClass.FirstName);
            Assert.AreEqual("Doe", destinationClass.LastName);
        }
        public void CloneInt64()
        {
            Assert.IsTrue(Cloneable <Int64> .CanClone());
            Assert.IsTrue(Cloneable <Int64> .CanShallowClone());
            Assert.IsTrue(Cloneable <Int64?> .CanClone());
            Assert.IsTrue(Cloneable <Int64?> .CanShallowClone());

            Assert.AreEqual((Int64)(-64), Cloneable <Int64> .Clone(-64));
            Assert.AreEqual((Int64)(-64), Cloneable <Int64> .ShallowClone(-64));

            Assert.AreEqual((Int64?)(-64), Cloneable <Int64?> .Clone(-64));
            Assert.AreEqual((Int64?)(-64), Cloneable <Int64?> .ShallowClone(-64));
            Assert.AreEqual((Int64?)(null), Cloneable <Int64?> .Clone(null));
            Assert.AreEqual((Int64?)(null), Cloneable <Int64?> .ShallowClone(null));
        }
        public void CloneInt16()
        {
            Assert.IsTrue(Cloneable <Int16> .CanClone());
            Assert.IsTrue(Cloneable <Int16> .CanShallowClone());
            Assert.IsTrue(Cloneable <Int16?> .CanClone());
            Assert.IsTrue(Cloneable <Int16?> .CanShallowClone());

            Assert.AreEqual((Int16)(-16), Cloneable <Int16> .Clone(-16));
            Assert.AreEqual((Int16)(-16), Cloneable <Int16> .ShallowClone(-16));

            Assert.AreEqual((Int16?)(-16), Cloneable <Int16?> .Clone(-16));
            Assert.AreEqual((Int16?)(-16), Cloneable <Int16?> .ShallowClone(-16));
            Assert.AreEqual((Int16?)(null), Cloneable <Int16?> .Clone(null));
            Assert.AreEqual((Int16?)(null), Cloneable <Int16?> .ShallowClone(null));
        }
        public void CloneUInt16()
        {
            Assert.IsTrue(Cloneable <UInt16> .CanClone());
            Assert.IsTrue(Cloneable <UInt16> .CanShallowClone());
            Assert.IsTrue(Cloneable <UInt16?> .CanClone());
            Assert.IsTrue(Cloneable <UInt16?> .CanShallowClone());

            Assert.AreEqual((UInt16)16, Cloneable <UInt16> .Clone(16));
            Assert.AreEqual((UInt16)16, Cloneable <UInt16> .ShallowClone(16));

            Assert.AreEqual((UInt16?)16, Cloneable <UInt16?> .Clone(16));
            Assert.AreEqual((UInt16?)16, Cloneable <UInt16?> .ShallowClone(16));
            Assert.AreEqual((UInt16?)null, Cloneable <UInt16?> .Clone(null));
            Assert.AreEqual((UInt16?)null, Cloneable <UInt16?> .ShallowClone(null));
        }
        public void CloneUInt32()
        {
            Assert.IsTrue(Cloneable <UInt32> .CanClone());
            Assert.IsTrue(Cloneable <UInt32> .CanShallowClone());
            Assert.IsTrue(Cloneable <UInt32?> .CanClone());
            Assert.IsTrue(Cloneable <UInt32?> .CanShallowClone());

            Assert.AreEqual((UInt32)32, Cloneable <UInt32> .Clone(32));
            Assert.AreEqual((UInt32)32, Cloneable <UInt32> .ShallowClone(32));

            Assert.AreEqual((UInt32?)32, Cloneable <UInt32?> .Clone(32));
            Assert.AreEqual((UInt32?)32, Cloneable <UInt32?> .ShallowClone(32));
            Assert.AreEqual((UInt32?)null, Cloneable <UInt32?> .Clone(null));
            Assert.AreEqual((UInt32?)null, Cloneable <UInt32?> .ShallowClone(null));
        }
        public void CloneObjectHierarchy()
        {
            var parent = new ParentClass();

            parent.Child = new ChildClass {
                Name = "John Doe"
            };

            Assert.IsTrue(Cloneable <ParentClass> .CanClone());
            Assert.IsTrue(Cloneable <ParentClass> .CanShallowClone());

            var parentClone = Cloneable <ParentClass> .Clone(parent);

            Assert.IsFalse(object.ReferenceEquals(parent.Child, parentClone.Child));
            Assert.AreEqual("John Doe", parentClone.Child.Name);
        }
        public void ShallowCloneToObjectHierarchyWithNullDestinationChild()
        {
            var source      = new ParentClass();
            var sourceChild = new ChildClass {
                Name = "John Doe"
            };

            source.Child = sourceChild;

            var destination = new ParentClass();

            Cloneable <ParentClass> .ShallowCloneTo(source, destination);

            Assert.IsTrue(object.ReferenceEquals(sourceChild, destination.Child));
            Assert.AreEqual(sourceChild.Name, destination.Child.Name);
        }
        public void CloneSingle()
        {
            Assert.IsTrue(Cloneable <Single> .CanClone());
            Assert.IsTrue(Cloneable <Single> .CanShallowClone());

            Assert.IsTrue(Cloneable <Single?> .CanClone());
            Assert.IsTrue(Cloneable <Single?> .CanShallowClone());

            Assert.AreEqual((Single)64, Cloneable <Single> .Clone(64));
            Assert.AreEqual((Single)64, Cloneable <Single> .ShallowClone(64));

            Assert.AreEqual((Single?)64, Cloneable <Single?> .Clone(64));
            Assert.AreEqual((Single?)64, Cloneable <Single?> .ShallowClone(64));
            Assert.AreEqual((Single?)null, Cloneable <Single?> .Clone(null));
            Assert.AreEqual((Single?)null, Cloneable <Single?> .ShallowClone(null));
        }
        public void CloneChar()
        {
            Assert.IsTrue(Cloneable <Char> .CanClone());
            Assert.IsTrue(Cloneable <Char> .CanShallowClone());

            Assert.IsTrue(Cloneable <Char?> .CanClone());
            Assert.IsTrue(Cloneable <Char?> .CanShallowClone());

            Assert.AreEqual('A', Cloneable <Char> .Clone('A'));
            Assert.AreEqual('A', Cloneable <Char> .ShallowClone('A'));

            Assert.AreEqual('A', Cloneable <Char?> .Clone('A'));
            Assert.AreEqual('A', Cloneable <Char?> .ShallowClone('A'));
            Assert.AreEqual(null, Cloneable <Char?> .Clone(null));
            Assert.AreEqual(null, Cloneable <Char?> .ShallowClone(null));
        }
        public void CloneDouble()
        {
            Assert.IsTrue(Cloneable <Double> .CanClone());
            Assert.IsTrue(Cloneable <Double> .CanShallowClone());

            Assert.IsTrue(Cloneable <Double?> .CanClone());
            Assert.IsTrue(Cloneable <Double?> .CanShallowClone());

            Assert.AreEqual((Double)128, Cloneable <Double> .Clone(128));
            Assert.AreEqual((Double)128, Cloneable <Double> .ShallowClone(128));

            Assert.AreEqual((Double?)128, Cloneable <Double?> .Clone(128));
            Assert.AreEqual((Double?)128, Cloneable <Double?> .ShallowClone(128));
            Assert.AreEqual((Double?)null, Cloneable <Double?> .Clone(null));
            Assert.AreEqual((Double?)null, Cloneable <Double?> .ShallowClone(null));
        }
        public void ClonePrimitiveArray()
        {
            int[] ints = new int[] { 1, 2, 3, 4, 5 };

            Assert.IsTrue(Cloneable <int[]> .CanClone());
            Assert.IsTrue(Cloneable <int[]> .CanShallowClone());

            int[] clonedInts = Cloneable <int[]> .Clone(ints);

            int[] shallowClonedInts = Cloneable <int[]> .ShallowClone(ints);

            Assert.IsFalse(ReferenceEquals(ints, clonedInts));
            Assert.IsFalse(ReferenceEquals(ints, shallowClonedInts));

            Assert.IsTrue(clonedInts.SequenceEqual(new int[] { 1, 2, 3, 4, 5 }));
            Assert.IsTrue(shallowClonedInts.SequenceEqual(new int[] { 1, 2, 3, 4, 5 }));
        }
        public void CannotCloneStructWithFuncField()
        {
            Assert.IsFalse(Cloneable <StructWithFuncField> .CanClone());
            Assert.IsFalse(Cloneable <StructWithFuncField> .CanShallowClone());

            Assert.IsFalse(Cloneable <StructWithFuncField?> .CanClone());
            Assert.IsFalse(Cloneable <StructWithFuncField?> .CanShallowClone());

            Assert.Throws <InvalidOperationException>(() => Cloneable <StructWithFuncField> .Clone(new StructWithFuncField()));
            Assert.Throws <InvalidOperationException>(() => Cloneable <StructWithFuncField> .ShallowClone(new StructWithFuncField()));

            Assert.Throws <InvalidOperationException>(() => Cloneable <StructWithFuncField?> .Clone(null));
            Assert.Throws <InvalidOperationException>(() => Cloneable <StructWithFuncField?> .ShallowClone(null));

            Assert.Throws <InvalidOperationException>(() => Cloneable <StructWithFuncField?> .Clone(new StructWithFuncField()));
            Assert.Throws <InvalidOperationException>(() => Cloneable <StructWithFuncField?> .ShallowClone(new StructWithFuncField()));
        }
        public void CloneException()
        {
            var source = new Exception("Bad mojo!");

            Assert.IsTrue(Cloneable <Exception> .CanClone());
            Assert.IsTrue(Cloneable <Exception> .CanShallowClone());

            var clone = Cloneable <Exception> .Clone(source);

            var shallowClone = Cloneable <Exception> .ShallowClone(source);

            Assert.IsFalse(ReferenceEquals(source, clone));
            Assert.IsFalse(ReferenceEquals(source, shallowClone));

            Assert.AreEqual(source.Message, clone.Message);
            Assert.AreEqual(source.Message, shallowClone.Message);
        }
        public void CloneDecimal()
        {
            Assert.IsTrue(Cloneable <decimal> .CanClone());
            Assert.IsTrue(Cloneable <decimal> .CanShallowClone());

            Assert.IsTrue(Cloneable <decimal?> .CanClone());
            Assert.IsTrue(Cloneable <decimal?> .CanShallowClone());


            Assert.AreEqual((decimal)128, Cloneable <decimal> .Clone(128));
            Assert.AreEqual((decimal)128, Cloneable <decimal> .ShallowClone(128));

            Assert.AreEqual((decimal?)128, Cloneable <decimal?> .Clone(128));
            Assert.AreEqual((decimal?)128, Cloneable <decimal?> .ShallowClone(128));
            Assert.AreEqual((decimal?)null, Cloneable <decimal?> .Clone(null));
            Assert.AreEqual((decimal?)null, Cloneable <decimal?> .ShallowClone(null));
        }
        public void CloneListOfValueType()
        {
            List <int> source = new List <int> {
                1, 2, 3, 4, 5
            };

            Assert.IsTrue(Cloneable <List <int> > .CanClone());
            Assert.IsTrue(Cloneable <List <int> > .CanShallowClone());

            List <int> clone        = source.Clone();
            List <int> shallowClone = source.ShallowClone();

            Assert.IsFalse(ReferenceEquals(source, clone));
            Assert.IsFalse(ReferenceEquals(source, shallowClone));

            Assert.IsTrue(clone.SequenceEqual(new int[] { 1, 2, 3, 4, 5 }));
            Assert.IsTrue(shallowClone.SequenceEqual(new int[] { 1, 2, 3, 4, 5 }));
        }
        public void CloneSelfReferencingClass()
        {
            var source = new CloneTestClass {
                FirstName = "John", LastName = "Doe"
            };

            source.InnerClass = source;

            var clone = Cloneable <CloneTestClass> .Clone(source);

            var shallowClone = Cloneable <CloneTestClass> .ShallowClone(source);

            Assert.IsFalse(object.ReferenceEquals(source, clone));
            Assert.IsFalse(object.ReferenceEquals(source, shallowClone));

            Assert.IsTrue(object.ReferenceEquals(clone, clone.InnerClass));
            Assert.IsTrue(object.ReferenceEquals(shallowClone, shallowClone.InnerClass));
        }
        public void CloneGuid()
        {
            Guid id = new Guid("6C31A07E-F633-479b-836B-9479CD7EF92F");

            Assert.IsTrue(Cloneable <Guid> .CanClone());
            Assert.IsTrue(Cloneable <Guid> .CanShallowClone());

            Assert.IsTrue(Cloneable <Guid?> .CanClone());
            Assert.IsTrue(Cloneable <Guid?> .CanShallowClone());

            Assert.AreEqual(id, Cloneable <Guid> .Clone(id));
            Assert.AreEqual(id, Cloneable <Guid> .ShallowClone(id));

            Assert.AreEqual(id, Cloneable <Guid?> .Clone(id));
            Assert.AreEqual(id, Cloneable <Guid?> .ShallowClone(id));
            Assert.AreEqual(null, Cloneable <Guid?> .Clone(null));
            Assert.AreEqual(null, Cloneable <Guid?> .ShallowClone(null));
        }
        public void CloneDateTime()
        {
            DateTime now = SystemClock.UtcNow;

            Assert.IsTrue(Cloneable <DateTime> .CanClone());
            Assert.IsTrue(Cloneable <DateTime> .CanShallowClone());

            Assert.IsTrue(Cloneable <DateTime?> .CanClone());
            Assert.IsTrue(Cloneable <DateTime?> .CanShallowClone());

            Assert.AreEqual(now, Cloneable <DateTime> .Clone(now));
            Assert.AreEqual(now, Cloneable <DateTime> .ShallowClone(now));

            Assert.AreEqual(now, Cloneable <DateTime?> .Clone(now));
            Assert.AreEqual(now, Cloneable <DateTime?> .ShallowClone(now));
            Assert.AreEqual(null, Cloneable <DateTime?> .Clone(null));
            Assert.AreEqual(null, Cloneable <DateTime?> .ShallowClone(null));
        }
        public void CloneTimeSpan()
        {
            TimeSpan source = TimeSpan.FromMinutes(5);

            Assert.IsTrue(Cloneable <TimeSpan> .CanClone());
            Assert.IsTrue(Cloneable <TimeSpan> .CanShallowClone());

            Assert.IsTrue(Cloneable <TimeSpan?> .CanClone());
            Assert.IsTrue(Cloneable <TimeSpan?> .CanShallowClone());

            Assert.AreEqual(source, Cloneable <TimeSpan> .Clone(source));
            Assert.AreEqual(source, Cloneable <TimeSpan> .ShallowClone(source));

            Assert.AreEqual(source, Cloneable <TimeSpan?> .Clone(source));
            Assert.AreEqual(source, Cloneable <TimeSpan?> .ShallowClone(source));
            Assert.AreEqual(null, Cloneable <TimeSpan?> .Clone(null));
            Assert.AreEqual(null, Cloneable <TimeSpan?> .ShallowClone(null));
        }
        public void CloneUIntPtr()
        {
            var source = new UIntPtr(42);

            Assert.IsTrue(Cloneable <UIntPtr> .CanClone());
            Assert.IsTrue(Cloneable <UIntPtr> .CanShallowClone());

            Assert.IsTrue(Cloneable <UIntPtr?> .CanClone());
            Assert.IsTrue(Cloneable <UIntPtr?> .CanShallowClone());

            Assert.AreEqual(source, Cloneable <UIntPtr> .Clone(source));
            Assert.AreEqual(source, Cloneable <UIntPtr> .ShallowClone(source));

            Assert.AreEqual(source, Cloneable <UIntPtr?> .Clone(source));
            Assert.AreEqual(source, Cloneable <UIntPtr?> .ShallowClone(source));
            Assert.AreEqual(null, Cloneable <UIntPtr?> .Clone(null));
            Assert.AreEqual(null, Cloneable <UIntPtr?> .ShallowClone(null));
        }
        public void CloneClassWithNonSerializedIllegalField()
        {
            Assert.IsTrue(Cloneable <ClassWithNonSerializedIllegalField> .CanClone());
            Assert.IsTrue(Cloneable <ClassWithNonSerializedIllegalField> .CanShallowClone());

            var source = new ClassWithNonSerializedIllegalField {
                Name = "John Doe"
            };

            var clone = Cloneable <ClassWithNonSerializedIllegalField> .Clone(source);

            Assert.IsNotNull(clone);

            clone = null;

            clone = Cloneable <ClassWithNonSerializedIllegalField> .ShallowClone(source);

            Assert.IsNotNull(clone);
        }
        public void CloneJaggedClassArray()
        {
            var source = new CloneTestClass[][]
            {
                new CloneTestClass[]
                {
                    new CloneTestClass {
                        FirstName = "John", LastName = "Doe"
                    },
                    new CloneTestClass {
                        FirstName = "Jane", LastName = "Smith"
                    }
                }
            };

            Assert.IsTrue(Cloneable <CloneTestClass[][]> .CanClone());
            Assert.IsTrue(Cloneable <CloneTestClass[][]> .CanShallowClone());

            var clone = Cloneable <CloneTestClass[][]> .Clone(source);

            var shallowClone = Cloneable <CloneTestClass[][]> .ShallowClone(source);

            Assert.IsFalse(object.ReferenceEquals(source, clone));
            Assert.IsFalse(object.ReferenceEquals(source, shallowClone));

            Assert.IsFalse(object.ReferenceEquals(source[0], clone[0]));
            Assert.IsFalse(object.ReferenceEquals(source[0][0], clone[0][0]));
            Assert.IsFalse(object.ReferenceEquals(source[0][1], clone[0][1]));

            Assert.IsTrue(object.ReferenceEquals(source[0], shallowClone[0]));
            Assert.IsTrue(object.ReferenceEquals(source[0][0], shallowClone[0][0]));
            Assert.IsTrue(object.ReferenceEquals(source[0][1], shallowClone[0][1]));

            Assert.AreEqual(source.Length, clone.Length);
            Assert.AreEqual(source.Length, shallowClone.Length);

            Assert.AreEqual("John", clone[0][0].FirstName);
            Assert.AreEqual("Doe", clone[0][0].LastName);
            Assert.AreEqual("Jane", clone[0][1].FirstName);
            Assert.AreEqual("Smith", clone[0][1].LastName);
        }
        public void CloneStructWithSelfReferencingClass()
        {
            var selfRefClass = new CloneTestClass {
                FirstName = "John", LastName = "Doe"
            };

            selfRefClass.InnerClass = selfRefClass;

            var source = new StructWithReferenceToSelfReferencingClass {
                Class = selfRefClass
            };

            var clone = Cloneable <StructWithReferenceToSelfReferencingClass> .Clone(source);

            var shallowClone = Cloneable <StructWithReferenceToSelfReferencingClass> .ShallowClone(source);

            Assert.IsFalse(object.ReferenceEquals(source.Class, clone.Class));
            Assert.IsTrue(object.ReferenceEquals(source.Class, shallowClone.Class));

            Assert.IsTrue(object.ReferenceEquals(clone.Class, clone.Class.InnerClass));
        }
        public void CloneMultipleReferencesToSameArray()
        {
            var child = new CloneTestClass[]
            {
                new CloneTestClass(),
                new CloneTestClass()
            };

            var source = new CloneTestClass[][]
            {
                child,
                child
            };

            var clone = Cloneable <CloneTestClass[][]> .Clone(source);

            Assert.IsFalse(object.ReferenceEquals(source, clone));
            Assert.IsFalse(object.ReferenceEquals(clone[0], child));
            Assert.IsFalse(object.ReferenceEquals(clone[1], child));

            Assert.IsTrue(object.ReferenceEquals(clone[0], clone[1]));
        }
        public void CloneClass()
        {
            var source = new CloneTestClass {
                FirstName = "John", LastName = "Doe"
            };

            Assert.IsTrue(Cloneable <CloneTestClass> .CanClone());
            Assert.IsTrue(Cloneable <CloneTestClass> .CanShallowClone());

            var clone = Cloneable <CloneTestClass> .Clone(source);

            var shallowClone = Cloneable <CloneTestClass> .ShallowClone(source);

            Assert.IsFalse(ReferenceEquals(source, clone));
            Assert.IsFalse(ReferenceEquals(source, shallowClone));

            Assert.AreEqual("John", clone.FirstName);
            Assert.AreEqual("Doe", clone.LastName);

            Assert.AreEqual("John", shallowClone.FirstName);
            Assert.AreEqual("Doe", shallowClone.LastName);
        }
        public void CloneMultidimensionalStructArray()
        {
            CloneTestStruct[,] source = new CloneTestStruct[, ]
            {
                {
                    new CloneTestStruct {
                        FirstName = "John", LastName = "Doe"
                    },
                    new CloneTestStruct {
                        FirstName = "Jane", LastName = "Smith"
                    }
                }
            };

            Assert.IsTrue(Cloneable <CloneTestStruct[, ]> .CanClone());
            Assert.IsTrue(Cloneable <CloneTestStruct[, ]> .CanShallowClone());

            var clone = Cloneable <CloneTestStruct[, ]> .Clone(source);

            var shallowClone = Cloneable <CloneTestStruct[, ]> .ShallowClone(source);

            Assert.AreEqual(source.Length, clone.Length);
            Assert.AreEqual(source.Length, shallowClone.Length);

            Assert.AreEqual("John", clone[0, 0].FirstName);
            Assert.AreEqual("Doe", clone[0, 0].LastName);

            Assert.AreEqual("Jane", clone[0, 1].FirstName);
            Assert.AreEqual("Smith", clone[0, 1].LastName);

            Assert.AreEqual("John", shallowClone[0, 0].FirstName);
            Assert.AreEqual("Doe", shallowClone[0, 0].LastName);

            Assert.AreEqual("Jane", shallowClone[0, 1].FirstName);
            Assert.AreEqual("Smith", shallowClone[0, 1].LastName);
        }