Search code examples
c#value-typereference-type

copying a value type that has reference type as a member


If I copy a Value Type that has a Reference Type member (string in my case), CLR does a shallow copy (book). So I wrote a small program just to experiment but cannot get the expected result. I am sure I am missing some detail here.

public class Program
{
    public static void Main(string[] args)
    {
        Console.WriteLine("First Example");
        //first example
        Point p1 = new Point();
        p1.Name = "firstPoint";
        p1.X = 10;
        p1.Y = 20;

        Point p2 = p1;

        p2.Name = "secondPoint";
        p2.X = 40;
        p2.Y = 50;

        p1.Print(); //Prints - Name: firstPoint, X:10, Y:20
                    //Expected - Name: secondPoint, X:10, Y:20
        p2.Print(); //Prints - Name: secondPoint, X:40, Y:50

        Console.ReadLine();
    }
}

public struct Point
{
    public string Name;
    public int X;
    public int Y;

    public void Print()
    {
        Console.WriteLine("Name: {0}, X: {1}, Y: {2}", this.Name.ToString(), this.X, this.Y);
    }
}

Solution

  • You have changed your whole reference type so it behaved like that instead of that you can try changing member of that reference type in order to verify and play around it.

    see below code for your reference:

    public class Program
    {
        public static void Main()
        {
            Console.WriteLine("First Example");
            //first example
            Point p1 = new Point();
            p1.store = new SomeClass();
            p1.store.Name = "Jenish";
            p1.Name = "firstPoint";
            p1.X = 10;
            p1.Y = 20;
    
            Point p2 = p1;
    
            p2.Name = "secondPoint";
            p2.store.Name = "Jenish2";
            p2.X = 40;
            p2.Y = 50;
    
            p1.Print(); //Prints - Name: firstPoint, X:10, Y:20
            p2.Print(); //Prints - Name: secondPoint, X:40, Y:50
    
            Console.ReadLine();
        }
    }
    
    public struct Point
    {
        
        public string Name;
        public int X;
        public int Y;
        public SomeClass store;
    
        public void Print()
        {
            Console.WriteLine("Name: {0}, X: {1}, Y: {2}, Name: {3}", this.Name.ToString(), this.X, this.Y, this.store.Name);
        }
    }
    
    public class SomeClass{
        public string Name {get; set;}
    }
    

    output

    First Example

    Name: firstPoint, X: 10, Y: 20, Name: Jenish2

    Name: secondPoint, X: 40, Y: 50, Name: Jenish2

    Here is fiddle for you.

    Below example demonstrate the case what happens when you changes whole reference type.

    public class Program
    {
        public static void Main()
        {
            Console.WriteLine("First Example");
            //first example
            Point p1 = new Point();
            p1.store = new SomeClass();
            p1.store.Name = "Jenish";
            p1.Name = "firstPoint";
            p1.X = 10;
            p1.Y = 20;
    
            Point p2 = p1;
    
            p2.Name = "secondPoint";
            p2.store = new SomeClass();
            p2.store.Name = "Jenish2";
            p2.X = 40;
            p2.Y = 50;
    
            p1.Print(); //Prints - Name: firstPoint, X:10, Y:20
            p2.Print(); //Prints - Name: secondPoint, X:40, Y:50
    
            Console.ReadLine();
        }
    }
    
    public struct Point
    {
        
        public string Name;
        public int X;
        public int Y;
        public SomeClass store;
    
        public void Print()
        {
            Console.WriteLine("Name: {0}, X: {1}, Y: {2}, Name: {3}", this.Name.ToString(), this.X, this.Y, this.store.Name);
        }
    }
    
    public class SomeClass{
        public string Name {get; set;}
    }
    

    Note: name is different in both the object.

    Here is fiddle for the second example.