Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object cloning in c# [duplicate]

Tags:

c#

object

clone

Consider this related question: Deep cloning objects

Is this really the best way to clone an object? (serialize/deserialize). Serialization seems a bit expensive to me.

My idea was to create a second constructor and just assign all variables. Would this approach be faster?

class Test
{

public Test(Test clone)
{
// clone ....
}
}
like image 249
Maik Klein Avatar asked Dec 12 '22 04:12

Maik Klein


1 Answers

It depends on what do you want to clone and why. If a shallow clone is fine, then:

private static T CloneShallow<T>(T i) {
    return
        (T)i.GetType()
            .GetMethod(
                "MemberwiseClone",
                BindingFlags.Instance | BindingFlags.NonPublic
            ).Invoke(i, null);
}

It's the fastest way to clone simple records of any type.

If you need full copy, but it's not time-critical, then:

private static T CloneFull<T>(T i) {
    if (Object.ReferenceEquals(i, null)) return default(T);
    var x = new XmlSerializer(i.GetType());
    using (var m = new MemoryStream()) {
        x.Serialize(m, i);
        m.Seek(0, SeekOrigin.Begin);
        return (T)x.Deserialize(m);
    }
}

The second one is about 70 times slower than the first one.

If you need full copy and the speed is important, consider using protobuf-net as serializer.

There's a lot of answers involving modification of the object you wish to clone, but often you just need to clone a simple record and you don't want to implement anything on it.

And if you wonder how slow CloneFull() is - on my computer (i5 661 @ 3.33GHz) with very simple record it took 360 ticks, which gives 36ns. Which is fast enough in most cases :)

like image 86
Harry Avatar answered Jan 02 '23 21:01

Harry