tags:

views:

1006

answers:

3

I have an object not written by myself that I need to clone in memory. The object is not tagged ICloneable or Serializable so deep cloning through the interface or serialization will not work. Is there anyway to deep clone this object? A non-safe win32 API call maybe?

+7  A: 

FYI Interfaces marked as ICloneable are not nessecarially deep copied. It is up to the implementor to implement ICloneable and there is no guarentee they will have cloned it. You say the object doesn't implement ISerializable but does it have the Serializable attribute?

Creating a deep copy via binary serialization is probally one of the easiest methods I know of, since you can clone any complex graph in 3-5 lines of code. Another option would be the XmlSerializer if the object can be XmlSerialized (You don't specificy any attributes for serialization or implement interfaces however if there is an IDictionary interface your hosed.

Outside of that I can't really think of anything. If all the data is publicy accessible you could do your own cloning routine. If its not you can still clone it by using reflection to get set the private data.

JoshBerke
Sorry.. I mistyped (and have corrected the question). I tried to use the BinaryFormatter, but the class does not have the Serializable attribute, so it bombed.
DaveK
Yep can you modify the source that's the best way to do this;-) I loved implementing my copy document feature in our app, serialize deserialize it change the identifer and bam!
JoshBerke
A: 

I think the only way you could do this is with some serious reflection to pick apart the object and all its members (which may themselves be other objects with members, etc). That's what the framework serializer would be doing, but it will only do it for things which have been marked appropriately.

I'm not sure if an industrial-grade reflection library like Mono.Cecil might have some stuff which helps.

I doubt you're come up with a robust general purpose solution (for example, static members might be hard to deal with properly), but you might make something work in a specific case.

Will Dean
It's possible to circumvent the framework serializer's instance on [Serializable] - see Mark's answer. You can trick it into doing the default serialization (save all fields) on any type, regardless of the presence of the attribute.
Daniel Earwicker
+2  A: 

The "deep" is the tricky bit. For a shallow copy, you could use reflection to copy the fields (assuming none are readonly, which is a big assumption) - but it would be very hard to get this to work (automatically) otherwise.

The other option is to provide the serializer yourself (and serialize to deep-clone) - a "serialization surrogate". Here's a VB example.

Marc Gravell
I've played around with the Surrogate and it seems to work fine as long as I'm only using standard types (strings, ints, etc). As soon as I try to add a class as a property I get the 'Serialize' tag missing error.
DaveK