6

I'm quite unsure what I should use in C# - both should in theory do the same, but I think both are quite easely overseen. Or is there another possibility I have to take in consideration?

I know in C++ you use copy-constructors. But in C# I have never heard much of them (they are just a ctor with self as parameter and should reassign all data)

Also should my copy-ctor deep copy all objects or only reassign them?

What is considered 'best practice' for this scenario?

  • In 10 or so years of using C#, I don't think I've ever needed to implement an object copy solution, or used Clone. Maybe I'm an oddity though. May I ask what your use case is? – David Arno Jul 14 '16 at 14:26
  • I need to clone data to not change the source, because when I allow a user to edit via a gui and I set the exact same instance as source and the user cancels all the changes are applied anyways, so I use a copy of it and only change the original instance when he presses ok in the dialog. – Mafii Jul 14 '16 at 14:36
  • @DavidArno: It is rare, but it does happen. Joseph Albahari notes a few specific cases in his book "C# in a Nutshell:" cloning a culture to provide a new starting point (the clone is always writable), automatic deep-cloning of XML elements to prevent them from having multiple parents, protecting the contents of an object from being modified (i.e. "defensive copying"), etc. – Robert Harvey Jul 14 '16 at 14:43
  • @mafii: Copy constructors in C# – Robert Harvey Jul 14 '16 at 14:45
  • 1
    I use clones sometimes when I have a DataContext object in WPF and I want to know if it changed since it was loaded. So when I load it, I clone it and compare the two later on. I think I usually use a constructor to do this. I tend to keep constructors at the top of the file so that I don't forget to modify the cloning code when I add/remove/change a property. – user2023861 Jul 14 '16 at 15:14
4

Use copy constructors. Here's why:

  1. IClonable semantics are ambiguous. Microsoft never specified whether a clone should be a shallow or deep copy.

  2. You can specify custom behavior in your copy constructor, such as giving each copy its own unique ID or only copying some fields and not others.

Further Reading
Copy constructor vs Clone in C#

  • 3
    (1) you can have a Clone method without implementing IClonable. Or you can call it ShallowClone() or DeepClone() or whatever you choose. (2) you can also do this in methods. – user2023861 Jul 14 '16 at 15:17
  • @user2023861: Choosing one strategy and sticking with it is as good a reason as any, and since the IClonable confusion is associated with methods, not constructors, I went the constructor route. – Robert Harvey Jul 14 '16 at 15:25
  • fair enough. I'm having a hard time comparing the two solutions. I can't think of something that one can do that the other can't. Consistency may be the best route – user2023861 Jul 14 '16 at 15:27
  • 1
    Using the .Clone() can be used with interfaces (not saying built in IClonable, but you own interfaces for your code). This can make it easier to use and test, because the code that needs to clone the object doesn't need to be coupled with the implementation of that object. – Caleb Jul 17 '16 at 6:32
2

I would go for the clone method if the class involved was polymorphic (so that an instance of the right runtime type was created).

Otherwise it's a matter of taste in my opinion.

0

With respect to modifying records when the user presses "ok" in the dialog, you must compare it with the database record instance. You cannot rely on cloning the original HTTP get because someone may have modified the record before you and you get race conditions.

If this is not the case, this has been covered by another thread and I am hoping it helps you out. https://stackoverflow.com/questions/78536/deep-cloning-objects

  • 1
    That's not really what this is about. It's about implementing undo functionality. – Robert Harvey Jul 14 '16 at 14:50
  • Consider a case where I have all the data in ram and the user can save it to a file. There's no remote access going on and I have no database. There is no reloading of files and no multiuser access - think of it as a bit like word. – Mafii Jul 14 '16 at 14:50
  • Something like deserializing an object in the stream and comparing the stream object instance with the serialized instance? – StackOverFowl Jul 14 '16 at 14:53
  • No, just a plain model in form of c# classes, which I edit if the user agrees and and I dont if he doesn't. And in the end he can save his changes to a text file (serialized) – Mafii Jul 14 '16 at 15:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.