I have some problems cloning an object hierarchie. It's a toolkit for modelling applications, the toolbox contains class instances as prototypes. But I'm having a hard time cloning these :)
The following code shows the problem:
public abstract class Shape {
protected List<UIElement> elements;
private Canvas canvas;
...
public Canvas getCanvas() { ... };
}
public class MovableShape : Shape {
protected ... propertyA;
private ... propertyXY;
...
}
public abstract class AbstractLayout : MovableShape, ... {
...
}
public class SomeLayoutClass : AbstractLayout, ... {
...
}
public class AContainingClass {
SomeLayoutClass Layout { get; set; }
...
}
When I insert an object of AContainingClass
into my project worksheet, it should be cloned. So far I tried manual cloning (which fails because of the private
fields in the base classes) and binary serialization (BinaryFormatter
and MemoryStreams
).
The first approach lacks a way to call the base.clone()
method (or am I wrong?), the latter does not work because UIElement
s aren't [Serializable]
.
Note: it must be a deep copy!
Any ideas? Thanks!
UPDATE
Just to clarify my manual cloning approach:
If each class has it's own Clone
method, how to call the Clone
method of the base class?
public class Shape { // not abstract any more
...
public Shape Clone() {
Shape clone = new Shape() { PropertyA = this.PropertyA, ... };
...do some XamlWriter things to clone UIElements...
return clone;
}
}
public class MovableShape : Shape {
...
public MovableShape Clone() {
// how to call base.Clone???
// this would be required because I have no access to the private fields!
}
}
If you are attempting to clone UIElements, use the XamlWriter to save to a string, though no method of cloning is foolproof. You then use XamlReader to load a copy. You could still run into issues. Things like handlers not being copied, x:Name being duplicated, etc. But for simple elements like Grid or Brush, it works great.
Edit 1: There is no generic way to clone anything, however:
1) If a clone function is written correctly, it will call the base Clone for you, and copy the base class stuff, too. If it isn't written correctly calling the base Clone won't help much, though you can call a private method this way.
2) If you have to, you can use Reflection to copy pretty much anything, even click handlers, from an old object to a new object.
3) XamlWriter and XamlReader will copy and instantiate heirarchies of objects, just minus certain properties.
Edit 2: Here's a common cloning design pattern I use in my class hierarchies. Assume base class shape, derived class circle:
Haven't tried it myself, but XamlWriter looks promising.
And here the function for it: