Reputation: 2610
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.
Upvotes: 0
Views: 578
Reputation:
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.
Upvotes: 1
Reputation: 31
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?
Upvotes: 2
Reputation: 10708
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
Upvotes: 6