2

Before I begin, I'm aware there are several other questions that 'answer' this question, but not in a way that I can quite understand. Here's what I'm referring to: Deep copying in C#

Why Copying in C# is a terrible idea

I've done a fair bit of research and I was hoping someone could explain to me how to set objects to the value of another object.

For example, let's say:

myObject bob;
bob = new myObject();
myObject joe
joe = bob

From what I can research, joe now points to bob's instance of bob. Do these objects still behave independently?

How would I create two objects, copy the contents of one to another, and have them be two separate objects, whose fields, methods and events occur separately?

I'm sorry for asking this question again, but I can't seem to find an explanation that makes sense to me anywhere else.

Community
  • 1
  • 1
Athena
  • 3,200
  • 3
  • 27
  • 35
  • After your assignment above, both bob and joe point to the same instance in memory. bob and joe can be thought of as pointer variables. To create a copy, create a new instance and then copy each member. This can be encoded in a method, of course. – 500 - Internal Server Error Oct 16 '13 at 19:38
  • One of the first questions I would ask myself is 'Why do I need an exact copy of this object?' You could consider looking into an Object Factory style pattern if you find you need a lot of similar/identical copies of an object that are independent of each other. – Vassi Oct 16 '13 at 19:38
  • Could you elaborate on what specifically those other answers don't answer for you? There doesn't seem to be any additional questions that those answers lack. It seems as if you are simply saying "I don't understand the answers", which is not really a question and if it was construed as one, it would be impossible to answer. – myermian Oct 16 '13 at 19:39
  • Possible duplicate: http://stackoverflow.com/questions/5359318/how-to-clone-objects – Jeroen Vannevel Oct 16 '13 at 19:40
  • 2
    You can either do a [deep or shallow copy](http://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy) ..Implement [ICloneable](http://msdn.microsoft.com/en-us/library/system.icloneable.aspx) interface and then to clone that object call the clone method...Though it's [not](http://stackoverflow.com/questions/699210/why-should-i-implement-icloneable-in-c) recommended to implement it..Create your own method instead! As it is done [here](http://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-an-object-in-net-c-specifically) byte by byte – Anirudha Oct 16 '13 at 19:41
  • If you want, you should learn a bit about C++ classes, structures and pointers, as it would help you to understand this behavior in C# (and in other object oriented languages). – Samuel Oct 16 '13 at 20:04
  • Thanks for the feedback. m-y, in response to your comment- The question is the same, but I was looking for a clearer answer. I didn't want to necro other questions so I figured I'd ask a new one. user2316005- didn't think of learning about C++ too, appreciate that parallel. – Athena Oct 17 '13 at 18:03

4 Answers4

6

They both point to the same instance.If you want two separate instances use the new operator to create a second.

Bob Provencher
  • 431
  • 2
  • 12
3

Let's go through each line:

myObject bob; // Creates a variable of type myObject, but it doesn't point anywhere
bob = new myObject(); // bob now points to a newly created myObject instance
myObject joe; // Creates a variable of type myObject, but it doesn't point anywhere
joe = bob; // joe now refers to the same object as bob

An important thing to keep in mind is that the last line copies over the value of the reference itself. Such as if bob points to address 1000, joe will also point there. Thus, if you change any data at this address, both joe and bob will point to that same data.

However, you're welcome to set joe to point somewhere else and it will not affect bob. In other words:

joe = null; // This will not null out bob

If you wanted to create a brand new instance of myObject, you'd have to do this:

joe = new myObject(); // This will also not affect bob

Now, if you're trying to create a new instance of myObject in memory and copy over all of the properties of an existing instance, you'd have to do this yourself:

joe = new myObject();
joe.X = bob.X; // Assuming X is not a reference itself
joe.Y = bob.Y; // ...or you'd have to do this recursively

.NET does not provide a way to do this copying for you. One common pattern is to make a constructor for myObject() that takes an instance of myObject and copies all its properties:

joe = new myObject(bob);
Mike Christensen
  • 88,082
  • 50
  • 208
  • 326
2

Yes, bob and joe would both be pointing to the exact same object there.

Copying of objects really needs to be done on a per-class basis. Let's say you have a class with only value types (some ints and strings perhaps). Copying every field of that would work just fine.

But now imagine if your class holds references to other objects (which is likely), if you just copy this object field by field, you will now have two different instances that is sharing some data (an open file, a network socket etc). So to reliably copy an object you should have that object create a copy of itself, since it knows what kind of data it holds.

So the answer is that there is no safe generic way of copying an object in C#.

Chris
  • 5,442
  • 17
  • 30
2

You are confusing data with methods here. Data define what a object is. E.g A circle of radius 2. Methods act on that data, e.g IncreaseRadius() When you copy, this data is copied, not methods. Methods just operate on class data and produce output specific to class data.

No. They are both pointing to same object. bob and joe are just 2 variable that are holding reference to same object in memory. If you change data through bob and read from joe, you will get new value.

The standard way is to implement ICloneable interface and use it to create a deep copy. By that i mean that you have to create a new object in Clone method and copy each data member to newly created object. If the data is another reference type then you have to clone it too.

ata
  • 8,853
  • 8
  • 42
  • 68