我正在使用一个名为BigNumDesc的类来表示数字。我有一个数字的锯齿状数组,代表一个矩阵。 我首先按以下方式声明这个矩阵:
BigNumDec[][] matrix = new BigNumDec[][] {
new BigNumDec[] { 1, 2 },
new BigNumDec[] { 3, 4 }
};
现在,我想要调用此方法:
static BigNumDec[][] GetStrictlyUpperTriangle(BigNumDec[][] matrix)
{
BigNumDec[][] newMatrix = new BigNumDec[matrix.Length][];
matrix.CopyTo(newMatrix, 0);
return null;
}
我在最后一行有一个断点。如果在观察窗口中,我取任何矩阵项,并更改它,它将改变newMatrix,因为所有BigNumDec都是引用类型(来自它的创建者的糟糕设计决定?)。我怎么能做到这一点?我需要对newMatrix进行修改,所以我必须先从矩阵中复制它。
编辑:现在尝试使用整数,但它发生的情况完全相同。我觉得价值类型不会发生吗?
BigNumDec是不可变的。
答案 0 :(得分:3)
它仍然在使用值类型的原因是因为您正在使用数组数组。你是浅层复制“外部”数组,它只是将引用复制到两个“内部”数组。
你没有证明BigNumDec
是不可变的(我希望如此)但如果是,你应该没问题,如果你只是深度复制数组。或者,您可以使用矩形数组[,]
而不是锯齿状数组[][]
吗?如果是这样,简单的副本就足够了。对于矩形阵列存在性能影响,请注意 - 值得对此进行测试以确定它是否对您有用。您获得了更好的引用位置,但实际的数组访问速度并不快。
答案 1 :(得分:1)
问题在于你初始化BigNumDec数组,你正在创建一个BigNumDec对象的一维数组。 [0] = {1,2},[1] = {3。4}。然后,您有效地复制引用这些对象,而不是它们的内容,因此值继续改变。
将您的初始化更改为:
BigNumDec[,] matrix = new BigNumDec[,] {
{ 1, 2 },
{ 3, 4 }
};
答案 2 :(得分:1)
如果您的对象是Serializable,则可以使用序列化实现深层复制。它的效率不高(按性能),但很简单。
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;
}
您必须将 BigNumDec 声明为[Serializable]:
[Serializable]
public class BigNumDec
{
//class content
}
(正如在其他答案中所述,如果你可以移动到二维数组而不是锯齿状,你会得到更好的解决方案)