5

I have 2 object of same class as following in c#.

Myclass obj1 = new Myclass();
Myclass obj2 = null;
obj2 = obj1;
obj1.Name = "abc";     //"abc" will also assign to obj2.Name. 

When I assign obj1.Name="abc", it will also assign to obj2.Name. I want to stop this. I have tried by const, sealed but I am not getting result. Can anybody suggest me how to stop reference of obj1 on obj2?

poke
  • 369,085
  • 72
  • 557
  • 602
NJ Bhanushali
  • 901
  • 1
  • 12
  • 21
  • You must create a new instance of Myclass of `obj2` to stop referencing from `obj1`. – Joel Legaspi Enriquez Jul 24 '15 at 06:32
  • 1
    Because `obj1` and `obj2` pointing the same objects. How about _not_ assign their references to each other? – Soner Gönül Jul 24 '15 at 06:32
  • 2
    [Clone it somehow.](https://msdn.microsoft.com/en-us/library/system.icloneable(v=vs.110).aspx) – Ry- Jul 24 '15 at 06:33
  • 1
    You have two *variables*. You don't have two *objects*, only **one**. – Lasse V. Karlsen Jul 24 '15 at 06:34
  • possible duplicate of [object assignment](http://stackoverflow.com/questions/2486297/object-assignment) – poke Jul 24 '15 at 06:34
  • try [MemberwiseClone](https://msdn.microsoft.com/en-us/library/system.object.memberwiseclone(v=vs.100).aspx) - also there are several SO answers on deep copy: [1](http://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-an-object-in-net-c-specifically), [2](http://stackoverflow.com/questions/11074381/deep-copy-of-a-c-sharp-object), [3](http://stackoverflow.com/questions/78536/deep-cloning-objects) and this [codeproj article](http://www.codeproject.com/Articles/38270/Deep-copy-of-objects-in-C) – Mark Mikofski Jul 24 '15 at 06:35
  • Thank you. It solved with Clone(). //obj2 = obj1.Clone(); – NJ Bhanushali Jul 24 '15 at 07:24

5 Answers5

4

You want to deep clone obj1:

Myclass obj1 = new Myclass();
Myclass obj2 = DeepClone(obj1);
obj1.Name = "abc"; 

One way to deep clone an object is to Serialize it and Deserialize it back.

Here's an example using json.net:

public T DeepClone<T>(T instance)
{
   return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(instance));
}
Amir Popovich
  • 29,350
  • 9
  • 53
  • 99
3

You should clone obj1. You can use MemberwiseClone().

Myclass obj2 = (Myclass)obj1.MemberwiseClone();
melihorhan
  • 198
  • 1
  • 2
  • 11
3

see my comment above. The msdn docs for MemberwiseClone cover this well.

in MyClass add the following method:

public class MyClass 
{
    ...
    // make a shallow copy
    public MyClass ShallowCopy()
    {
        return (MyClass) this.MemberwiseClone();
    }
}

then you can use ShallowCopy() method to create obj2

Myclass obj1 = new Myclass();
Myclass obj2 = obj1.ShallowCopy();
obj1.Name = "abc";     //"abc" won't assign to obj2.Name. 
Mark Mikofski
  • 19,398
  • 2
  • 57
  • 90
1

The behavior you're seeing is because you simply have two references to a single object. It doesn't matter which reference you use to obtain the object, it's still the same object. I am assuming this is because MyClass is a reference type (i.e. a class).

Since it seems you want value type semantics here, perhaps you want MyClass to be a struct, so that a copy is created on assignment:

struct MyClass
{
    private string _name;
    public MyClass(string name)
    {
        _name = name;
    }

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
}

Then your original code works as you wanted:

MyClass joe = new Myclass("Joe");
MyClass bob = joe;
bob.Name = "Bob";

Console.WriteLine(bob.Name); // Bob
Console.WriteLine(joe.Name); // Joe

See it in action here: http://ideone.com/Xwnqsa

Asad Saeeduddin
  • 46,193
  • 6
  • 90
  • 139
-1

When you write obj2 = obj1, you are making obj2 point to the object that is obj1 is pointing at. You aren't creating a new separate instance that has the same value as obj1. So in order to prevent any changes that you make to obj1 appear in obj2, you need to make a deep copy of obj1, like the following:

obj2 = new MyClass(obj1);
obj1.Name = "abc";
Parth Shah
  • 2,060
  • 1
  • 23
  • 34