public void ShallowCloneClassHierarchyWithIllegalFieldTypeInReferencedClass()
        {
            Assert.IsTrue(Cloneable <ParentClassWithNonCloneableChild> .CanShallowClone());

            Assert.IsNull(Cloneable <ParentClassWithNonCloneableChild> .ShallowClone(null));
            Assert.IsNotNull(Cloneable <ParentClassWithNonCloneableChild> .ShallowClone(new ParentClassWithNonCloneableChild()));
        }
        public void CloneJaggedStructArray()
        {
            var source = new CloneTestStruct[][]
            {
                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);
        }
        public void CloneJaggedPrimitiveArray()
        {
            var source = new int[][]
            {
                new int[] { 1, 2, 3, 4, 5 }
            };

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

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

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

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

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

            Assert.AreEqual(source[0][0], clone[0][0]);
            Assert.AreEqual(source[0][1], clone[0][1]);
            Assert.AreEqual(source[0][2], clone[0][2]);

            Assert.AreEqual(source[0][0], shallowClone[0][0]);
            Assert.AreEqual(source[0][1], shallowClone[0][1]);
            Assert.AreEqual(source[0][2], shallowClone[0][2]);
        }
        public void CloneListOfReferenceType()
        {
            List <CloneTestClass> source = new List <CloneTestClass> {
                new CloneTestClass {
                    FirstName = "John", LastName = "Doe"
                }
            };

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

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

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

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

            Assert.AreEqual(1, clone.Count);
            Assert.AreEqual(1, shallowClone.Count);

            Assert.IsFalse(ReferenceEquals(source[0], clone[0]));
            Assert.IsTrue(ReferenceEquals(source[0], shallowClone[0]));

            Assert.AreEqual("John", clone[0].FirstName);
            Assert.AreEqual("Doe", clone[0].LastName);
        }
        public void CloneStruct()
        {
            var source = new CloneTestStruct {
                FirstName = "John", LastName = "Doe"
            };

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

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

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

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

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

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

            clone = Cloneable <CloneTestStruct?> .Clone(source).Value;

            shallowClone = Cloneable <CloneTestStruct?> .ShallowClone(source).Value;

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

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

            Assert.IsNull(Cloneable <CloneTestStruct?> .Clone(null));
            Assert.IsNull(Cloneable <CloneTestStruct?> .ShallowClone(null));
        }
        public void CloneMultidimensionalPrimitiveArray()
        {
            int[,] source = new int[, ] {
                { 1, 2, 3 }
            };

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

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

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

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

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

            Assert.IsTrue(source[0, 0].Equals(clone[0, 0]));
            Assert.IsTrue(source[0, 1].Equals(clone[0, 1]));
            Assert.IsTrue(source[0, 2].Equals(clone[0, 2]));

            Assert.IsTrue(source[0, 0].Equals(shallowClone[0, 0]));
            Assert.IsTrue(source[0, 1].Equals(shallowClone[0, 1]));
            Assert.IsTrue(source[0, 2].Equals(shallowClone[0, 2]));
        }
        public void CloneStructArray()
        {
            var 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 clones = Cloneable <CloneTestStruct[]> .Clone(source);

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

            Assert.IsFalse(object.ReferenceEquals(source, clones));
            Assert.IsFalse(object.ReferenceEquals(source, shallowClones));

            Assert.AreEqual(source.Length, clones.Length);
            Assert.AreEqual(source.Length, shallowClones.Length);

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

            Assert.AreEqual("Jane", clones[1].FirstName);
            Assert.AreEqual("Smith", clones[1].LastName);
        }
        public void CloneString()
        {
            Assert.IsTrue(Cloneable <string> .CanClone());
            Assert.IsTrue(Cloneable <string> .CanShallowClone());

            Assert.AreEqual("Testing...", Cloneable <string> .Clone("Testing..."));
            Assert.AreEqual("Testing...", Cloneable <string> .ShallowClone("Testing..."));
        }
        public void CannotCloneDelegate()
        {
            Assert.IsFalse(Cloneable <Action> .CanClone());
            Assert.IsFalse(Cloneable <Action> .CanShallowClone());

            Assert.Throws <InvalidOperationException>(() => Cloneable <Action> .Clone(null));
            Assert.Throws <InvalidOperationException>(() => Cloneable <Action> .ShallowClone(null));
        }
        public void CannotCloneClassWithIntPtrField()
        {
            Assert.IsFalse(Cloneable <ClassWithFuncField> .CanClone());
            Assert.IsFalse(Cloneable <ClassWithFuncField> .CanShallowClone());

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

            Assert.Throws <InvalidOperationException>(() => Cloneable <ClassWithFuncField> .Clone(new ClassWithFuncField()));
            Assert.Throws <InvalidOperationException>(() => Cloneable <ClassWithFuncField> .ShallowClone(new ClassWithFuncField()));
        }
        public void CannotCloneDerivedClassWithDeletegateField()
        {
            Assert.IsFalse(Cloneable <DerivedClassWithDelegateField> .CanClone());
            Assert.IsFalse(Cloneable <DerivedClassWithDelegateField> .CanShallowClone());

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

            Assert.Throws <InvalidOperationException>(() => Cloneable <DerivedClassWithDelegateField> .Clone(new DerivedClassWithDelegateField()));
            Assert.Throws <InvalidOperationException>(() => Cloneable <DerivedClassWithDelegateField> .ShallowClone(new DerivedClassWithDelegateField()));
        }
        public void CannotCloneClassWithIllegalArrayFieldType()
        {
            Assert.IsFalse(Cloneable <ClassWithFuncArray> .CanClone());
            Assert.IsFalse(Cloneable <ClassWithFuncArray> .CanShallowClone());

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

            Assert.Throws <InvalidOperationException>(() => Cloneable <ClassWithFuncArray> .Clone(new ClassWithFuncArray()));
            Assert.Throws <InvalidOperationException>(() => Cloneable <ClassWithFuncArray> .ShallowClone(new ClassWithFuncArray()));
        }
        public void CloneMultidimensionalClassArray()
        {
            CloneTestClass[,] source = new CloneTestClass[, ]
            {
                {
                    new CloneTestClass {
                        FirstName = "John", LastName = "Doe"
                    },
                    new CloneTestClass {
                        FirstName = "Jane", LastName = "Smith"
                    }
                }
            };

            source[0, 1].InnerClass = source[0, 1];

            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.AreEqual(source.Length, clone.Length);
            Assert.AreEqual(source.Length, shallowClone.Length);

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

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

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