Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a constructor class to make a copy of an existing class instance

I'm new to OOP, so please bear with me. I am having an issue making a copy of an existing class using a class constructor. Below is an example where I create an initial instance of a class, make a copy of it using a class constructor, and then modify a property value in the initial class. This also modifies the same value in the copied class, which is not the behavior I want to achieve. (I want it to remain as the initial class existed before the modification.) Thanks in advance for your assistance!

class Program
{
    static void Main(string[] args)
    {
        // Make initial instance, make a copy, and write the copied values to console
        myClass myInitialInstance = new myClass();
        myClass myOtherInstance = new myClass(myInitialInstance);
        Console.WriteLine("Copied Instance: {0}, {1}, {2}", myOtherInstance.Input1[0], myOtherInstance.Input1[1], myOtherInstance.Input1[2]);

        // Make change to initial instance
        myInitialInstance.Input1 = new double[] { 10, 10, 10 };

        // Notice in the display that myOtherInstance inherits the {10,10,10} values from myInitialInstance
        Console.WriteLine("Initial Instance: {0}, {1}, {2}", myInitialInstance.Input1[0], myInitialInstance.Input1[1], myInitialInstance.Input1[2]);
        Console.WriteLine("Copied Instance: {0}, {1}, {2}", myOtherInstance.Input1[0], myOtherInstance.Input1[1], myOtherInstance.Input1[2]);
        Console.ReadKey();

    }
}

public class myClass
{
    public double[,] AllPoints { get; set; }
    public double[] Input1 { get { return GetRow(0); } set { SetRow(0, value); } }
    public double[] Input2 { get { return GetRow(1); } set { SetRow(1, value); } }

    private double[] GetRow(int i) { return new double[] { AllPoints[i, 0], AllPoints[i, 1], AllPoints[i, 2] }; }
    private void SetRow(int i, double[] value)
    {
        AllPoints[i, 0] = value[0];
        AllPoints[i, 1] = value[1];
        AllPoints[i, 2] = value[2];
    }

    public myClass() { AllPoints = new double[2, 3]; }

    public myClass(myClass anotherInstance) { AllPoints = anotherInstance.AllPoints; }
}

The above code produces the following output:

Copied Instance: 0, 0, 0 Initial Instance: 10, 10, 10 Copied Instance: 10, 10, 10

I would expect the output to be the following:

Copied Instance: 0, 0, 0 Initial Instance: 10, 10, 10 Copied Instance: 0, 0, 0

like image 293
KevinChrencik Avatar asked Jan 07 '23 06:01

KevinChrencik


1 Answers

Currently, your copy constructor simply assigns the reference of anotherInstance to the current instance of MyClass being created. This leads to the fact that any change to the original array will be visible to the newly created class, as they're pointing to the same array. What you actually want to do is copy the array in your copy constructor.

public MyClass(MyClass anotherInstance) 
{
    Array.Copy(anotherInstance.AllPoints,
               this.AllPoints, 
               anotherInstance.AllPoints.Length); 
}
like image 146
Yuval Itzchakov Avatar answered Jan 25 '23 23:01

Yuval Itzchakov