using System; using System.IO; using System.Reflection; using System.Diagnostics; using System.Globalization; using System.Collections.Generic; using System.Runtime.Serialization.Formatters.Binary; public class Test { [Serializable] public class DataItem { public Int32 Property1 { get; set; } public String Property2 { get; set; } public Int32 Property3 { get; set; } public DataItem Parent; public List Children; } public static void Main() { DataItem root = CreateTestData(); DataItem testItems1 = Clone(root); //DataItem testItems2 = CopyProperties(root); Measure("Serialize", delegate { DataItem items2 = Clone(root); }); //Measure("Reflection", // delegate // { // DataItem items3 = CopyProperties(root); // }); Console.ReadLine(); } private static int _levels = 5; private static int _childCount = 5; private static int _identity = 0; private static int GetNextId() { return _identity++; } static DataItem CreateTestData() { DataItem root = new DataItem { Property1 = GetNextId(), Property2 = GetNextId().ToString(), Property3 = GetNextId(), Children = new List() }; CreateChildren(root); return root; } static void CreateChildren(DataItem parent, int level = 0) { for (int i = 0; i < _childCount; i++) { DataItem child = new DataItem { Property1 = GetNextId(), Property2 = GetNextId().ToString(), Property3 = GetNextId(), Parent = parent }; parent.Children.Add(child); if (level < _levels) { child.Children = new List(); CreateChildren(child, level + 1); } } } static T Clone(T target) { using (MemoryStream stream = new MemoryStream()) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, target); stream.Position = 0; T result = (T)formatter.Deserialize(stream); return result; } } //static void CopyProperties(S source, T target) where T : class //{ // Type type = typeof(T); // PropertyInfo[] properties = source.GetType().GetProperties(); // foreach (PropertyInfo property in properties) // { // PropertyInfo targetProperty = type.GetProperty(property.Name); // if (targetProperty != null) // targetProperty.SetValue(target, property.GetValue(source, null), null); // } //} //static T[] CopyProperties(S[] source) where T : class, new() //{ // if (source == null) // throw new ArgumentNullException("source"); // T[] result = new T[source.Length]; // for (Int32 loop = 0; loop < source.Length; loop++) // { // result[loop] = new T(); // CopyProperties(source[loop], result[loop]); // } // return result; //} static void Measure(String message, Action method) { Int64 mem = GC.GetTotalMemory(true); Int64 gcCount = GC.CollectionCount(0); DateTime now = DateTime.Now; Stopwatch stopwatch = Stopwatch.StartNew(); method(); TimeSpan elapsed = stopwatch.Elapsed; // DONTTOUCH: // It is intended to call GetTotalMemory with forceFullCollection: false // before CollectionCount call. Double tempMemDelta = Math.Max(GC.GetTotalMemory(false) - mem, 0); Int64 gcCountDelta = GC.CollectionCount(0) - gcCount; String elapsedString = elapsed.TotalSeconds.ToString("00.0000", CultureInfo.InvariantCulture); String memDeltaInKb = (tempMemDelta / 1024).ToString("0.00 KB", CultureInfo.InvariantCulture); Console.WriteLine(@"{0}: Elapsed: {1} s, MemDelta: {2,10}, GC count: {3} ", message, elapsedString, memDeltaInKb, gcCountDelta); } }