1

Below is my class

 public Class Test 
 {
     int id {get;set;}
     string name {get;set;}
 }

I am creating an object of this class and assigning values.

   var obj = new Test();
   obj.id = 1;
   obj.name = "test";
   var newobj = obj;
   newobj.name ="NewTest";

Below is the output

  Console.WriteLine(obj.name); //NewTest
  Console.WriteLine(newobj.name); //NewTest

Why value of obj is changing when i change value of a property present in new obj. I know its very solution, I am not sure why I am not able to find. I don't want value of obj to get changed if i changed value in newobj.

Max Maddy
  • 309
  • 1
  • 4
  • 9
  • 3
    The value of `obj.name` is changing when you change `newobj.name` because they are the *same thing*. `newobj` and `obj` both point to the same location in memory. They are just different *references* to the same *object*. If you want to create a true copy, you will have to create a method which constructs a `new Test()` and sets the properties of that new object accordingly. – Glorin Oakenfoot Jun 10 '16 at 13:17
  • 1
    with other words - newobj is another reference to the same object that obj references – JeffRSon Jun 10 '16 at 13:17
  • `Test` is a reference type. – Amit Kumar Ghosh Jun 10 '16 at 13:17
  • the way to ensure these objects are not linked is to create a new 'newobj' – NoviceProgrammer Jun 10 '16 at 13:19

5 Answers5

5

You are not creating a copy, you are merely assigning the reference of an object (obj) to another variable (newobj). Accessing either of them points to the same location in memory.

To create a copy of an object, you have to clone it. See https://stackoverflow.com/a/78612/1028323 https://stackoverflow.com/a/129395/1028323 for example.

public static T DeepClone<T>(T obj)
{
 using (var ms = new MemoryStream())
 {
   var formatter = new BinaryFormatter();
   formatter.Serialize(ms, obj);
   ms.Position = 0;

   return (T) formatter.Deserialize(ms);
 }
}
Community
  • 1
  • 1
Alex
  • 7,901
  • 1
  • 41
  • 56
3

As mentioned in the comments, both obj and newObj are pointing to the same underlying in-memory object, which is why changing something on one also changes something on the other. This is because they are reference types (as opposed to value types). If you want two different objects, you have a couple of options. The first is to create a new object and manually assign the properties:

var test1 = new Test() { id = 1, name = "Foo }
var test2 = new Test() { id = test1.id, name = test1.name }

The second option is to clone the object. While there are many ways of doing this (reflection, serialization, expression trees, third party libraries), I've found that using serialization is the simplest way to perform cloning provided that you aren't intending on doing it thousands of times per second. See the answer below for information on using the BinaryFormatter to clone objects.

Cloning List<T>

Community
  • 1
  • 1
DVK
  • 2,726
  • 1
  • 17
  • 20
2

newobj ain't creating a new instance... it's just another pointer to the same instance you created with var obj = new Test();

The_Black_Smurf
  • 5,178
  • 14
  • 52
  • 78
0
var newobj = obj; 

This is causing the reference of obj to get assigned to newobj. There really isn't a difference in the memory location where they point to with the above statement. If you want to have a obj with same values but remain unaffected when values of newobj change you should do it this way.

   var obj = new Test();
   obj.id = 1;
   obj.name = "test";
   var newobj = new Test();
   newobj.id = obj.id;
   newobj.name = obj.name;
   newobj.name ="NewTest";
Pushpendra
  • 1,694
  • 14
  • 27
0

You buy a new apartment. You get a set of keys that give you access to that apartment. You hire someone to clean up your apartment and you give him a copy of your set keys so that he can get inside. When you get home from work late at night, your apartment is clean! How come?

This dumb analogy is exactly whats happening in your code:

  • The instance of Test you created with new is your apartment.
  • obj is your set of keys.
  • newObj is the copy you gave the cleaning service.
  • Changing Name is cleaning up your apartment (modify the object in some way).

The important thing to clearly understand here is that the value of obj or newObj is not the instance of Test. The value stored in the variable is the memory address where the object lives.

Same as a key gives you access to your apartment, variables obj and newObj give you access to the object they are pointing at. When you copy the variable obj to newObj you are simply copying the means to access the object (memory address), not the object itself.

Things are radically diferent with value types, but thats another story.

InBetween
  • 32,319
  • 3
  • 50
  • 90