2009-10-23 130 views
1

我正在使用一个名为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; 
} 

我在最后一行一个突破点。如果在监视窗口中,我接受任何矩阵项目并对其进行更改,它将会改变太新的矩阵,因为所有BigNumDec都是参考类型(来自其创建者的糟糕设计决策?)。我怎样才能做到这一点?我需要对newMatrix进行修改,所以我必须首先从矩阵中复制它。

编辑:现在尝试使用整数,但它发生的是一样的。我会不会发生值类型?

BigNumDec是不可变的。

回答

3

其值类型仍在发生的原因是因为您使用的是数组数组。你很浅 - 复制“外部”数组,它只是将引用复制到两个“内部”数组中。

您还没有表现出BigNumDec是否是不可改变与否(我希望如此),但如果是这样,你应该罚款,如果你只是在阵列深层复制。或者,您可以使用矩形阵列[,]而不是锯齿阵列[][]?如果是这样,一个简单的副本就足够了。对矩形阵列有性能影响,请介意 - 值得测试一下,看看它是否会对您造成问题。你会得到更好的参考位置,但实际的数组访问速度并不快。

+0

一个简单的它适用于整数。它能与BigNumDec一起使用吗?我会说不。 – 2009-10-23 07:35:30

+0

它似乎工作。现在我很困惑。 – 2009-10-23 07:36:27

+0

你能否解释一下,为什么不可改变或者不会在这里有所作为?当它检测到我想改变它的值时,它是否会在幕后创建一个新的? – 2009-10-23 07:39:13

1

问题出在您初始化BigNumDec数组时,您正在创建一个BigNumDec对象的一维数组。 [0] = {1,2},[1] = {3.4}。然后,您就有效地复制了这些对象的引用,而不是它们的内容,因此这些值继续发生变化。

你的初始化更改为:

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

如果你的对象是可序列可以使用序列化实现深拷贝。这不是非常有效(按性能),但很简单。

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 
} 

(在其他的答案在这里说,如果你能移动到二维数组,而不是锯齿状你会得到更好的解决方案)