8

I am using an instance class from a third-party DLL, and I need to do a deep copy on a particular instance. The class is not marked as Serializable, and therefore I can not use this suggested method using BinaryFormatter.

How can I get a deep copy of this object without using serialization?

Community
  • 1
  • 1
Josh Stodola
  • 81,538
  • 47
  • 180
  • 227

3 Answers3

5

I've been using Copyable with great success. It uses reflection under the hood. It is open-sourced. Be sure to read Limitations and pitfalls to see if you can use it.

Josh Stodola
  • 81,538
  • 47
  • 180
  • 227
Kenny Eliasson
  • 2,047
  • 15
  • 23
  • I believe this will work for me, thanks! I understand the pitfalls, and thankfully what I am currently working with has absolutely no unmanaged resources. Thanks again, I'll let you know how it works out. – Josh Stodola Jan 28 '10 at 20:44
  • (updated your answer to include SEO-link, and confirmed that library uses reflection) – Josh Stodola Jan 28 '10 at 20:47
  • One caveat not mentioned with *Copyable* is that classes like it don't know anything about outside references into a data structure. Suppose, for example, that within a class there's a reference to a single-element array of String, and suppose that every second some other class puts the current time of day into the first (only) element of that array. A clone of the original class object would contain a string with the time of day the object was copied, rather than a continuously-changing one. – supercat Feb 18 '11 at 21:14
  • You can use a mapper, i suggest UltraMapper https://github.com/maurosampietro/UltraMapper. It uses ExpressionTrees instead of Reflection and thus it is 1000x faster than reflection – Mauro Sampietro Apr 23 '17 at 09:18
2

One suggestion is to use Json serialization (which uses reflection, and doesn't rely on the [Serializable] attribute) to serialize and deserialize into a copy. For example, using the Json.Net library:

var copiedObject = JsonConvert.DeserializeObject<Snapshot>(
    JsonConvert.SerializeObject(sourceSnapshotObject));
codekaizen
  • 26,990
  • 7
  • 84
  • 140
aranjan
  • 48
  • 7
0

You can't (or perhaps shouldn't is what I'm looking for).

If the class is not designed to be serialized, and it does not provide you a means to clone it (i.e. in the form of a clone or copy method) then you cannot easily automatically do this. (And in addition, if this facility is not provided, then you probably should not do this, as the class is probably not designed with this type of usage in mind.)

However, if you really want to do it and you're in a full trust environment, then of course you can do some dirty stuff using FormatterServices.GetUninitializedObject and then using reflection to copy the field values from one object to the other. But this is almost certainly a bad idea.

Greg Beech
  • 133,383
  • 43
  • 204
  • 250