Beispiel #1
0
        public void TestSeparateDelegateIsCreatedForNestedOuter()
        {
            var ilCloner = new IlCloner();
            var obj      = new TestCollectionItem
            {
                Contents = new TestCollection
                {
                    new TestCollectionItem {
                        Text = "ZZZ"
                    },
                    new TestCollectionItem {
                        Text = "XXX"
                    },
                    new TestCollectionItem {
                        Text = "YYY"
                    },
                },
                Text = "ZZZZ"
            };

            var cloner = ilCloner.CreateClonerDelegate(obj);

            /*
             * IL_0000: ldarg.1
             * IL_0001: stloc.0
             * IL_0002: ldarg.0
             * IL_0003: call       Int32 get_Count()/System.Collections.CollectionBase
             * IL_0008: stloc.1
             * IL_0009: ldc.i4.0
             * IL_000a: stloc.2
             * IL_000b: br.s       IL_0025
             * IL_000d: ldloc.0
             * IL_000e: ldarg.0
             * IL_000f: ldloc.2
             * IL_0010: callvirt   System.Object get_Item(Int32)/System.Collections.IList
             * IL_0015: ldnull
             *      -- Here is the problem, one extra argument
             *      -- The cached method was the outer one.
             * IL_0016: call       TestCollectionItem DeepClone_TestCollectionItem(TestCollectionItem)/DynGen0000_CloneState_TestCollectionItem
             * IL_001b: callvirt   Int32 Add(System.Object)/System.Collections.IList
             * IL_0020: pop
             * IL_0021: ldloc.2
             * IL_0022: ldc.i4.1
             * IL_0023: add
             * IL_0024: stloc.2
             * IL_0025: ldloc.2
             * IL_0026: ldloc.1
             * IL_0027: blt.s      IL_000d
             * IL_0029: ret
             */
            try
            {
                cloner(obj);
            }
            catch (Exception e)
            {
                var k = e + "";
                var j = 0;
            }
        }
Beispiel #2
0
        public void TestSameNonGenericTypesClonedDifferently()
        {
            var ilCloner = new IlCloner();

            var example = new TestTwoNonGenericMembersSameType()
            {
                ListA = new TestNonGenericList
                {
                    "a", "b", "c", "d"
                },
                ListB = new TestNonGenericList
                {
                    1, 2, 3, 4
                }
            };

            var cloner = ilCloner.CreateClonerDelegate(example);

            var exampleCloned = cloner(example);

            Assert.IsFalse(Object.ReferenceEquals(example, exampleCloned));
            Assert.IsFalse(Object.ReferenceEquals(example.ListA, exampleCloned.ListA));
            Assert.IsFalse(Object.ReferenceEquals(example.ListB, exampleCloned.ListB));

            Assert.IsTrue(example.ListA.Cast <string>().SequenceEqual(exampleCloned.ListA.Cast <string>()));
            Assert.IsTrue(example.ListB.Cast <int>().SequenceEqual(exampleCloned.ListB.Cast <int>()));
        }
Beispiel #3
0
        public void ClassAndStructCloning()
        {
            try
            {
                var ilCloner = new IlCloner();

                var rootAsReferenceType = ExampleClass.GenerateExampleObject();
                var rootAsValueType     = ExampleClass.GenerateExampleObject().nestedStruct;

                var clonerRef   = ilCloner.CreateClonerDelegate <ExampleClass>();
                var clonerValue = ilCloner.CreateClonerDelegate <ExampleStruct>();

                var clonedReference = clonerRef(rootAsReferenceType);
                var clonedStruct    = clonerValue(rootAsValueType);

                Assert.IsTrue(rootAsReferenceType.Equals(clonedReference));
                Assert.IsTrue(rootAsValueType.Equals(clonedStruct));

                Assert.IsTrue(rootAsReferenceType.Equals(rootAsReferenceType.Clone()));
            }
            catch (Exception e)
            {
                var j = e + "";

                throw;
            }
        }
Beispiel #4
0
        public void TestArrayCloning()
        {
            var ilCloner = new IlCloner();

            var exampleArray = new[]
            {
                Enumerable.Range(0, 10)
                .Select(i => ExampleClass.GenerateExampleObject())
                .ToArray()
            }
            .ToArray();

            var cloner = IlCloner.CreateCloner(exampleArray);

            var cloned = cloner(exampleArray);

            Assert.IsFalse(Object.ReferenceEquals(exampleArray, cloned));

            for (var i = 0; i < exampleArray.Length; i++)
            {
                Assert.IsFalse(Object.ReferenceEquals(exampleArray[i], cloned[i]));

                for (var j = 0; j < exampleArray[i].Length; j++)
                {
                    Assert.IsFalse(Object.ReferenceEquals(exampleArray[i][j], cloned[i][j]));
                    Assert.IsTrue(exampleArray[i][j].Equals(cloned[i][j]));
                }
            }
        }
Beispiel #5
0
        public void TestExplicitStraightCopy()
        {
            var obj = new TestClassWithStraightCopiedProp
            {
                Prop = new TestClassWithPropertyExclusion
                {
                    PropA = "ASDF"
                }
            };

            var cloner = IlCloner.Fluent(obj)
                         .AlwaysStraightCopy(x => x.Prop)
                         .CreateCloner();

            var clonerDeep = Cloner.CreateClonerDelegate(obj);

            var cloned = cloner(obj);

            Assert.IsFalse(Object.ReferenceEquals(obj, cloned));
            Assert.IsTrue(Object.ReferenceEquals(obj.Prop, cloned.Prop));

            var clonedDeep = clonerDeep(obj);

            Assert.IsFalse(Object.ReferenceEquals(obj, clonedDeep));
            Assert.IsFalse(Object.ReferenceEquals(obj.Prop, clonedDeep.Prop));
            Assert.AreEqual(obj.Prop.PropA, clonedDeep.Prop.PropA);
        }
Beispiel #6
0
        public void TestInitializedMembersNotDoublyInitialized()
        {
            var exampleObj   = new TestClassWithInitializedMembers();
            var countAtStart = TestClassWithConstructCount.Counter;
            var cloner       = new IlCloner().CreateClonerDelegate(exampleObj);

            cloner(exampleObj);

            Assert.AreEqual(2, TestClassWithConstructCount.Counter - countAtStart);
        }
Beispiel #7
0
        public void TestTypeWithCustomConstructor()
        {
            var ilCloner = new IlCloner();

            ilCloner.DefineCustomConstructor <TestClassWithoutCtor>(c => TestClassWithoutCtor.Create());

            var obj = TestClassWithoutCtor.Create();

            obj.PropA = "JJJ";

            ilCloner.CreateClonerDelegate <TestClassWithoutCtor>()(obj);
        }
Beispiel #8
0
        public void TestDecimalType()
        {
            var cloner = new IlCloner();
            var obj    = new TestClassWithDecimal();
            var del    = cloner.CreateClonerDelegate(obj);

            var cloned = del(obj);

            Assert.IsFalse(Object.ReferenceEquals(obj, cloned));
            Assert.AreEqual(obj.DecimalField, cloned.DecimalField);
            Assert.AreEqual(obj.DecimalProp, cloned.DecimalProp);
        }
Beispiel #9
0
        public void TestIndexerBeingUsedForIListGeneric()
        {
            var ilCloner = new IlCloner();

            var list = new TestList <int>();

            for (var i = 0; i < 4; i++)
            {
                list.Add(i);
            }

            var cloner  = IlCloner.CreateCloner(list);
            var newList = cloner(list);

            Assert.IsTrue(list.GetIndexerHit, "Get indexer was not accessed while cloning list");
        }
Beispiel #10
0
        public void TestStructCloning()
        {
            var obj = new TestStructOnly
            {
                PropA = "ASDF",
                PropB = 1234
            };

            var cloner = new IlCloner();
            var del    = cloner.CreateClonerDelegate(obj);

            var output = del(obj);

            Assert.AreEqual(obj.PropA, output.PropA);
            Assert.AreEqual(obj.PropB, output.PropB);
        }
Beispiel #11
0
        public void TestStructWithClassCloning()
        {
            var obj = new TestNestedStruct_IS_CLASS
            {
                StructProp = new TestNestedClass_IS_STRUCT
                {
                    ClassProp = new TestNestedStruct_IS_CLASS
                    {
                        StructProp = new TestNestedClass_IS_STRUCT()
                    }
                }
            };

            var cloner = new IlCloner();

            var clonerStruct = cloner.CreateClonerDelegate(obj.StructProp);
            var clonedStruct = clonerStruct(obj.StructProp);
        }
Beispiel #12
0
        public void TestClassWithStructCloning()
        {
            var obj = new TestNestedStruct_IS_CLASS
            {
                StructProp = new TestNestedClass_IS_STRUCT
                {
                    ClassProp = new TestNestedStruct_IS_CLASS
                    {
                        StructProp = new TestNestedClass_IS_STRUCT()
                    }
                }
            };

            var cloner = new IlCloner();

            var clonerClass = cloner.CreateClonerDelegate(obj);
            var clonedClass = clonerClass(obj);
        }
Beispiel #13
0
        public void TestAbstractMember()
        {
            var cloner = new IlCloner();

            var instance = new TestClassWIthAbstractMember
            {
                PropAbstract = new TestClassImplementingAbstract
                {
                    PropA = "ASDF"
                }
            };

            var del    = cloner.CreateClonerDelegate(instance);
            var output = del(instance);

            Assert.IsFalse(Object.ReferenceEquals(instance, output));
            Assert.IsFalse(Object.ReferenceEquals(instance.PropAbstract, output.PropAbstract));
            Assert.AreEqual(instance.PropAbstract.GetType(), output.PropAbstract.GetType());
            Assert.AreEqual(instance.PropAbstract.PropA, output.PropAbstract.PropA);
        }
Beispiel #14
0
        public void TestInterfaceMember()
        {
            var cloner = new IlCloner();

            var instance = new TestClassWithInterfaceMember
            {
                PropInterface = new TestClassImplementingInterface
                {
                    PropA = "ASDF"
                }
            };

            var del    = cloner.CreateClonerDelegate(instance);
            var output = del(instance);

            Assert.IsFalse(Object.ReferenceEquals(instance, output));
            Assert.IsFalse(Object.ReferenceEquals(instance.PropInterface, output.PropInterface));
            Assert.AreEqual(instance.PropInterface.GetType(), output.PropInterface.GetType());
            Assert.AreEqual(instance.PropInterface.PropA, output.PropInterface.PropA);
        }
Beispiel #15
0
        public void TestNestedStructCloning()
        {
            var obj = new TestStructWithNestedStruct
            {
                Nested = new TestStructOnly
                {
                    PropA = "ASDF",
                    PropB = 1234
                },
                PropC = "ZZZZ"
            };

            var cloner = new IlCloner();
            var del    = cloner.CreateClonerDelegate(obj);

            var output = del(obj);

            Assert.AreEqual(obj.Nested.PropA, output.Nested.PropA);
            Assert.AreEqual(obj.Nested.PropB, output.Nested.PropB);
            Assert.AreEqual(obj.PropC, output.PropC);
        }
Beispiel #16
0
        public void TestNonGenericListContainingNonGenericListOfSameType()
        {
            var ilCloner = new IlCloner();

            var example = new TestTwoNonGenericMembersSameType()
            {
                ListC = new TestNonGenericList()
            };

            example.ListC.Add(new TestNonGenericList {
                1, 2, 3, 4
            });

            var cloner = IlCloner.CreateCloner(example);

            var exampleCloned = cloner(example);


            Assert.IsFalse(Object.ReferenceEquals(example.ListC, exampleCloned.ListC));
            Assert.IsFalse(Object.ReferenceEquals(example.ListC[0], exampleCloned.ListC[0]));
        }
Beispiel #17
0
        public void TestThreadSafety()
        {
            var ilCloner = new IlCloner();

            var threadCount    = Math.Max(4, Environment.ProcessorCount - 1);
            var threadsRunning = 0;
            var start          = false;

            var tasks = Enumerable.Range(0, threadCount)
                        .Select(x => Task.Run(() =>
            {
                Interlocked.Increment(ref threadsRunning);
                SpinWait.SpinUntil(() => start);

                ilCloner.CreateClonerDelegate <ExampleClass>();
            }))
                        .ToArray();

            SpinWait.SpinUntil(() => threadsRunning == threadCount);
            start = true;

            Task.WaitAll(tasks);
        }
Beispiel #18
0
        public void TestNonGenericListCloning()
        {
            var ilCloner = new IlCloner();

            var example = new AsList
            {
                "A", "B", "C"
            };

            var cloner = ilCloner.CreateClonerDelegate <AsList>();

            var cloned = cloner(example);

            Assert.IsFalse(Object.ReferenceEquals(example, cloned));
            Assert.IsTrue(example.SequenceEqual(cloned));

            var nonGenList = new ExampleOldSchoolList();

            ((IList)nonGenList).Add(example);
            ((IList)nonGenList).Add(example);
            ((IList)nonGenList).Add(example);
            ((IList)nonGenList).Add(example);
            ((IList)nonGenList).Add(example);
            ((IList)nonGenList).Add(example);

            var clonerNonGen = IlCloner.CreateCloner(nonGenList);
            var clonedNonGen = clonerNonGen(nonGenList);

            Assert.IsFalse(Object.ReferenceEquals(nonGenList, clonedNonGen));
            Assert.IsTrue(example.SequenceEqual(cloned));

            for (var i = 0; i < nonGenList.Count; i++)
            {
                Assert.IsFalse(Object.ReferenceEquals(((IList)nonGenList)[i], ((IList)clonedNonGen)[i]));
            }
        }
Beispiel #19
0
 public IlClonerFluent()
 {
     _cloner = new IlCloner();
 }
Beispiel #20
0
 public IlClonerFluent(IlCloner cloner)
 {
     _cloner = cloner;
 }
Beispiel #21
0
        public static Action Benchmark <T>(T obj, int countToRun = 1000000, bool cloneProps = true)
            where T : class, ICloneable
        {
            var message = "";
            var timer   = new Stopwatch();

            timer.Start();

            IlCloner.Default.ShouldCloneProperties = cloneProps;
            IlCloner.Default.UseExistingCloners    = false;

            var example = obj;

            var cloneGenStart = timer.Elapsed;
            var cloner        = IlCloner.CreateCloner <T>();

            message +=
                $"{(timer.Elapsed - cloneGenStart).TotalMilliseconds.ToString("n2")}ms to generate cloner." +
                Environment.NewLine;

            // Dry run
            cloner(example);
            example.Clone();

            var actions = new[]
            {
                new { Name = "IL Generated", Action = new Action(() => cloner(example)) },
                new { Name = "C# Clone() method", Action = new Action(() => example.Clone()) }
            };

            Action iteration = () =>
            {
                var    deferred     = new List <Action>();
                var    maxClonesSec = 0.0;
                double?minClonesSec = null;

                var messages = actions.ToDictionary(a => a.Name, a => new List <string>());

                string fastest = null;

                foreach (var a in actions)
                {
                    GC.Collect();
                    System.Threading.Thread.Sleep(1000);

                    var startTime = timer.Elapsed;

                    for (var i = 0; i < countToRun; i++)
                    {
                        a.Action();
                    }

                    var totalTime = timer.Elapsed - startTime;
                    var clonesSec = (countToRun / totalTime.TotalSeconds);

                    maxClonesSec = Math.Max(maxClonesSec, clonesSec);

                    if (minClonesSec.HasValue)
                    {
                        minClonesSec = Math.Min(minClonesSec.Value, clonesSec);
                    }
                    else
                    {
                        minClonesSec = clonesSec;
                    }

                    deferred.Add(
                        () =>
                    {
                        messages[a.Name].Add($"{clonesSec.ToString("n2")} clones per second.");

                        if (clonesSec != maxClonesSec)
                        {
                            var frac = (clonesSec / maxClonesSec);

                            messages[a.Name].Add($"{(100.0 - frac * 100.0).ToString("0.00")}% ({frac.ToString("0.00")} times) slower than best performer.");
                        }

                        if (clonesSec != minClonesSec.Value)
                        {
                            var frac = (clonesSec / minClonesSec).Value;

                            messages[a.Name].Add($"{(frac * 100.0 - 100.0).ToString("0.00")}% ({frac.ToString("0.00")} times) faster than worst performer.");
                        }

                        if (clonesSec == maxClonesSec)
                        {
                            fastest = a.Name;
                        }
                    }
                        );
                }

                deferred.ForEach(d => d());

                var nameFieldLength = actions.Max(a => a.Name.Length) + 4;

                message += string.Join(
                    Environment.NewLine + Environment.NewLine,
                    actions
                    .Select(a =>
                {
                    return(string.Join(
                               Environment.NewLine,
                               messages[a.Name].Select((m, idx) =>
                    {
                        if (idx == 0)
                        {
                            return $"{a.Name}:".PadRight(nameFieldLength) + m;
                        }
                        else if (idx == 1 && a.Name == fastest)
                        {
                            return "".PadRight(a.Name.Length, '^').PadRight(nameFieldLength) + m;
                        }
                        else
                        {
                            return "".PadRight(nameFieldLength) + m;
                        }
                    })
                               ));
                })
                    );

                Console.WriteLine(message);
                Console.ReadLine();

                message = "";
            };

            iteration();

            return(iteration);
        }
Beispiel #22
0
        public void TestTypeWithoutConstructor()
        {
            var ilCloner = new IlCloner();

            ilCloner.CreateClonerDelegate <TestClassWithoutCtor>();
        }