public void TestCloningAllDeepCloneables() { PluginLoader.Assemblies.ToArray(); bool success = true; foreach (Type deepCloneableType in ApplicationManager.Manager.GetTypes(typeof(IDeepCloneable))) { // skip types that explicitely choose not to deep-clone every member if (excludedTypes.Contains(deepCloneableType)) continue; // test only types contained in HL plugin assemblies if (!PluginLoader.Assemblies.Contains(deepCloneableType.Assembly)) continue; // test only instantiable types if (deepCloneableType.IsAbstract || !deepCloneableType.IsClass) continue; IDeepCloneable item = null; try { item = (IDeepCloneable)Activator.CreateInstance(deepCloneableType, nonPublic: false); } catch { continue; } // no default constructor IDeepCloneable clone = null; try { clone = (IDeepCloneable)item.Clone(new Cloner()); } catch (Exception e) { TestContext.WriteLine(Environment.NewLine + deepCloneableType.FullName + ":"); TestContext.WriteLine("ERROR! " + e.GetType().Name + @" was thrown during cloning. All IDeepCloneable items with a default constructor should be cloneable when using that constructor!"); success = false; continue; } var intersections = CheckTotalInequality(item, clone).Where(x => x.GetType().FullName.StartsWith("HeuristicLab")); if (!intersections.Any()) continue; if (!ProcessEqualObjects(item, intersections)) success = false; } Assert.IsTrue(success, "There are potential errors in deep cloning objects."); }
/// <summary> /// Creates a deep clone of this repeated field. /// </summary> /// <remarks> /// If the field type is /// a message type, each element is also cloned; otherwise, it is /// assumed that the field type is primitive (including string and /// bytes, both of which are immutable) and so a simple copy is /// equivalent to a deep clone. /// </remarks> /// <returns>A deep clone of this repeated field.</returns> public RepeatedField <T> Clone() { int len = Count; if (len > 0) { bool isDeepCloner = base[0] is IDeepCloneable <T>; RepeatedField <T> clone = new RepeatedField <T>(len); if (isDeepCloner) { for (int i = 0; i < len; i++) { IDeepCloneable <T> item = base[i] as IDeepCloneable <T>; if (item != null) { clone.Add(item.Clone()); } else { clone.Add(base[i]); } } } else { for (int i = 0; i < len; i++) { clone.Add(base[i]); } } return(clone); } return(new RepeatedField <T>()); }
public T Get() { var path = GetPath(); //Console.WriteLine(string.Join(",", path)); object container = this; for (int i = 0; i < path.Count; ++i) { if (i < path.Count - 1) { container = container .GetType() .GetField(path[i], BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(container); } else { T value = (T)container .GetType() .GetField(path[i], BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(container); IDeepCloneable <T> cloneable = value as IDeepCloneable <T>; if (cloneable == null) { return(value); } return(cloneable.Clone()); } } throw new Exception("Something went wrong"); }
public IDeepCloneable Clone(IDeepCloneable obj) { if (obj == null) { return(null); } IDeepCloneable clone; if (cache.TryGetValue(obj, out clone)) { return(clone); } else { return(obj.Clone(this)); } }