开发者

Deep copying reference types

开发者 https://www.devze.com 2022-12-09 10:35 出处:网络
I am using a class called BigNumDesc that represents a number. I have a jagged arr开发者_如何学Pythonay of that numbers, that represent a matrix.

I am using a class called BigNumDesc that represents a number. I have a jagged arr开发者_如何学Pythonay of that numbers, that represent a matrix. I first declare this matrix the following way:

    BigNumDec[][] matrix = new BigNumDec[][] {
        new BigNumDec[] { 1, 2 },
        new BigNumDec[] { 3, 4 }
    };

Now, I have this method I want to call:

static BigNumDec[][] GetStrictlyUpperTriangle(BigNumDec[][] matrix)
{
    BigNumDec[][] newMatrix = new BigNumDec[matrix.Length][];
    matrix.CopyTo(newMatrix, 0);
    return null;
}

I have a break-point in the last line. If in the watch window, I take any item of matrix, and change it, it will change too newMatrix, as all BigNumDec are reference types(bad design decision from the creator of it?). How can I accomplish this? I need to make modifications to newMatrix, so I must copy it first from matrix.

edit: Tried the same now with ints, but it's happening just the same. I'd it wouldn't happen with value types?

BigNumDec is immutable.


The reason it's still happening with value types is because you're using an array of arrays. You're shallow-copying the "outer" array, which just copies the references to the two "inner" arrays.

You haven't shown whether BigNumDec is immutable or not (I would hope so) but if it is, you should be fine if you just deep copy the array. Alternatively, can you use a rectangular array [,] instead of a jagged array [][]? If so, a simple copy would suffice. There are performance implications with rectangular arrays, mind you - it's worth testing this to see whether it'll be a problem for you. You get better locality of reference, but the actual array access isn't as fast.


The issue is with your initialisation of the BigNumDec array, you are creating a 1-dimensional array of BigNumDec objects. [0] = { 1, 2 }, [1] = { 3. 4 }. You are then effectively copying the references those objects, not their content, hence why the values continue to change.

Change your initialisation to:

BigNumDec[,] matrix = new BigNumDec[,] {
    { 1, 2 },
    { 3, 4 }
};


If your objects are Serializable you can implement deep copy using serialization. It's not very efficient (by performance) but it's simple.

public BigNumDec[][] CopyUsingSerialization(BigNumDec[][] original)
{
    var binaryFormatter = new BinaryFormatter();
    var serializationStream = new MemoryStream();
    binaryFormatter.Serialize(serializationStream, original);
    serializationStream.Position = 0;
    var copy = (BigNumDec[][])binaryFormatter.Deserialize(serializationStream);
    return copy;
}

You have to declare the BigNumDec as [Serializable]:

[Serializable]
public class BigNumDec
{
    //class content
}

(as said in other answers here, if you can move to two dimensional array instead of jagged you'll get better solution)

0

精彩评论

暂无评论...
验证码 换一张
取 消