1

I have this code:

List<Employee> employeesCopy = JsonConvert.DeserializeObject<List<Employee>>(JsonConvert.SerializeObject(employees));

Where the Employee object has properties such as a Name, DateOfBirth, Department etc.

How efficient is this code to use for a deep copy of a list of employee objects that would not exceed a size of 200,000?

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
  • One very easy way to answer this question would be to simply try it - you could very quickly knock together some code which creates a list of 200,000 `Employee` objects and use a `Stopwatch` to time how long it takes – Ben Cottrell Aug 28 '18 at 08:11
  • 2
    I guess you left out the other half of the question, efficiency as compared to what? But as @BenCottrell mentioned the best approach is to just roll up some benchmarks and pick your favorite – TheGeneral Aug 28 '18 at 08:15
  • @BenCottrell Elapsed [time] =00:00:01.5838072. That's actually pretty good for 200,000 employee objects in my opinion. –  Aug 28 '18 at 08:35
  • @TheGeneral I guess compared to just creating my own deep copy class. –  Aug 28 '18 at 08:35

1 Answers1

0

As mentioned in comments above, make a code sample for the 2 methods you want to compare. But there's more to it; if you write clone methods for every class, that's a lot of repetitive code with a higher chance of creating bugs.

If you use JSON serialization/deserialization however, you can make a generic extension method that will work for any object.

Implementation from another SO answer (code copied from answer):

/// <summary>
/// Perform a deep Copy of the object, using Json as a serialisation method. NOTE: Private members are not cloned using this method.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
public static T CloneJson<T>(this T source)
{
    // Don't serialize a null object, simply return the default for that object
    if (Object.ReferenceEquals(source, null))
    {
        return default(T);
    }

    // initialize inner objects individually
    // for example in default constructor some list property initialized with some values,
    // but in 'source' these items are cleaned -
    // without ObjectCreationHandling.Replace default constructor values will be added to result
    var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace };

    return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source), deserializeSettings);
}

To make this work with copying properties of an object that are interfaces, you have to add TypeNameHandling = TypeNameHandling.Auto to the JsonSerializerSettings for both serialization and deserialization (taken from this SO answer)

Joshua VdM
  • 628
  • 5
  • 16