3

Can serializing an object to JSON and immediately deserializing it back to the original object type be a valid way to deep copy an object.

I am asking mostly for languages like C# and Java, but would this be different across different languages?

Are there any issues that might occur by doing this?

yitzih
  • 3,018
  • 3
  • 27
  • 44
  • I don't see any, and yes it would create a perfect copy of the original object, but it's probably faster to just use the basic way as this needs both serializing and deserializing. I wouldn't say it's a good practice at all.* – N.K May 25 '18 at 14:35
  • I would recommend against it. Main reason is that circular references and functions cannot be converted to JSON. First ones generate an error, second ones are simply ignored. Better implement a proper recursive deep copy function if it doesn't exist in the language. – Kaddath May 25 '18 at 14:37
  • I say go for it, especially if your types are complex including parent/child relationships or reference types you don't have access to modify to add deep cloning code to. JSON serializers are mature, fast, and easy to use. Writing your own deep-copy cloner can be a major undertaking (reference loop handling, etc). You could even use a binary serializer, but I don't think using serialization as a cloning tool is a bad thing. – Ron Beyer May 25 '18 at 14:57
  • Have you looked at [Deep cloning objects](https://stackoverflow.com/q/78536) and [How do you do a deep copy of an object in .NET (C# specifically)?](https://stackoverflow.com/q/129389)? – dbc May 25 '18 at 16:00

1 Answers1

0

Seems logical, but might be a bit inefficient. I take it the object in question is just a simple poco.

You could use reflection to do this too.

This code will copy the properties of an object and return an instance of the new copy

public TTranslateTo TranslateTo<TTranslateTo>()
{
    var target = Activator.CreateInstance<TTranslateTo>();

    foreach (var p1 in GetObjectTypeProperties)
    {
        var p2 =
            target.GetType()
                .GetProperties()
                .FirstOrDefault(p => string.Equals(p.Name, p1.Name, StringComparison.CurrentCultureIgnoreCase) && p.PropertyType == p1.PropertyType);

        p2?.SetValue(target, p1.GetValue(this));
    }

    return target;
}

private IEnumerable<PropertyInfo> GetObjectTypeProperties => GetType()
    .GetProperties();

You could include this code in a base class giving you access to copy functions on all objects.

Ross Miller
  • 656
  • 3
  • 9
  • I believe what you posted is a shallow-copy mechanism. `p1.GetValue(this)` will return a reference for reference types, you would have to recursively call this for anything other than a value type. – Ron Beyer May 25 '18 at 14:48
  • Which is why I mentioned adding it as a base, you could then recursively call on any complex type. That would mean though any complex nested types requiring the base class to invoke this method. – Ross Miller May 25 '18 at 14:49
  • That works for types that you have access to modify, but what if one of the properties is `int[] SomeArray { get; set; }`? Or a `Dictionary`, `List`... – Ron Beyer May 25 '18 at 14:50
  • True. It would have to modified to detect the type and deal with it appropriately, with its own copy mechanism. Deep copies are problematic in this way. :( – Ross Miller May 25 '18 at 14:52