0

I have a class like this :

Public Class Dog{
   public Dog(string name, int age){
      Name = name;
      Age = age;
   }

   public string Name { get; set; }
   public int Age { get; set; }
}

Then I create an instance of this class

Dog jake = new Dog("Jake", 3);

And When I try to copy the Class and change its properties like

Dog buster = jake;
buster.Name = "Buster";

when I do this, The Name in jake will change too

How can I avoid this ?

Note that the class I'm working with contains so much properties and it will make it much easier for me if I can just copy the class and change the one property I want.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Ayman El Temsahi
  • 2,600
  • 2
  • 17
  • 27
  • 7
    See here http://stackoverflow.com/questions/78536/deep-cloning-objects. Right now you are only copying the *reference* to the object, which is why changing a property of that object changes both. They refer to the same object. – eddie_cat Jun 19 '14 at 19:18
  • in C++ this copies a variable. not in C# http://www.albahari.com/valuevsreftypes.aspx – AK_ Jun 19 '14 at 19:21

3 Answers3

6

This will happen because of the way memory works in C#. Each class object is actually a pointer to an object in memory - when you assign one variable to another, you're still using the same pointer and, thus, modifying the same data when you make a change to one object.

Technically speaking, if you made all your objects structs, they would copy around just fine, because structures are values types and thus pass copies. This, however, is highly inadvisable because it limits usage, particularly with polymorphism, and is a bad idea for memory management of objects with lots of members.

The BEST way to solve this is to implement a function on class Dog which allows you to copy the data into a new Dog object. Thus, you would call

Dog buster = jake.Clone();
buster.Name = "Buster";

And in Clone, copy all properties from the current Dog object into a new Dog object.

EDIT: Going back to c++ roots, it's also common to implement a "Copy constructor" which takes a parameter of the same type in and makes a deep copy. IE

Dog jake = new Dog() { Name = "Jake" };
Dog buster = new Dog(jake) { Name = "Buster" };

NOTE: The above syntax uses the curly brackets, which allows you to set properties and fields from your class as soon as you create it. While technically compiler sugar, it is very good at making instantiation calls a lot more succinct

David
  • 10,458
  • 1
  • 28
  • 40
2

To build on the answer provided by @Aravol, if you have many properties you can look into getting/setting the properties in your cloned object using reflection to get the value of the properties from the object you are cloning from. See here:

Can I set a property value with Reflection?

Community
  • 1
  • 1
rezidual
  • 31
  • 4
1

When you do Dog buster = jake. you create a variable pointing to jake

So when you do buster.name = buster you're technically changing jakes name.

MGHandy
  • 363
  • 1
  • 3
  • 11