0

This is an addendum to a previous question I asked about copying classes.

The basic answer to the previous question (copying classes not as reference type) was to use a memberwise clone method to avoid keeping links between the two classes.

Doing this on a class with only int values works, but this breaks apart as soon as I introduce arrays in the mix. See the script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyClass
{
    public int[] myNumber;

    public MyClass ShallowCopy()
    {
        return (MyClass)this.MemberwiseClone();
    }
}

public class Test : MonoBehaviour
{
    Dictionary<string, MyClass> myDictionary1 = new Dictionary<string, MyClass>();
    Dictionary<string, MyClass> myDictionary2 = new Dictionary<string, MyClass>();

    void Start()
    {
        myDictionary1.Add("a", new MyClass() { myNumber = new int[] { 1, 1 } });
        myDictionary1.Add("b", new MyClass() { myNumber = new int[] { 2, 2 } });

        myDictionary2["b"] = myDictionary1["a"].ShallowCopy();
        myDictionary2["b"].myNumber[0] = 3;

        Debug.Log(myDictionary1["a"].myNumber[0]); //output 3, I'd want it to still be 1
    }
}

I've tried implementing the ShallowCopy method (implemented in line 9 and used in line 25) and it doesn't work. I should implement a DeepCopy method, but I don't know how to formulate it applied to arrays.

My new DeepCopy function would be something like

public MyClass DeepCopy()
{
    MyClass other = (MyClass)this.MemberwiseClone();
    other.myNumber = ?????????????????????? //int[] deep copy
    return other;
}

But I have no idea how to formulate a copy of the array. I've found a similar thread dealing with this, but I couldn't adapt the solution to my case.

Thanks in advance!

Kenneth K.
  • 2,987
  • 1
  • 23
  • 30
man-teiv
  • 419
  • 3
  • 16

1 Answers1

2

If you know that your array is going to be full of value types like int, or you have reference types and you want both arrays to refer to the same instance, you can use CopyTo

int[] copyTarget = new int[copyFrom.length];
copyFrom.CopyTo(copyTarget, 0);

If your array can/does have reference types in it, and you don't want the new array to reference the same instances, you will have to instead move through the elements doing a memberwise clone of each:

int[] copyTarget = new int[copyFrom.length];
for(int i = 0; i < copyTarget.Length; i++)
{
    copyTarget[i] = copyFrom[i].MemberwiseClone();
}
pquest
  • 3,151
  • 3
  • 27
  • 40