C# 深度复制引用类型
我正在使用一个名为BigNumDesc的类,它表示一个数字。我有一个参差不齐的数字数组,代表一个矩阵。 我首先以以下方式声明此矩阵:C# 深度复制引用类型,c#,.net,C#,.net,我正在使用一个名为BigNumDesc的类,它表示一个数字。我有一个参差不齐的数字数组,代表一个矩阵。 我首先以以下方式声明此矩阵: BigNumDec[][] matrix = new BigNumDec[][] { new BigNumDec[] { 1, 2 }, new BigNumDec[] { 3, 4 } }; 现在,我想调用这个方法: static BigNumDec[][] GetStrictlyUpperTriangle(Bi
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,所以我必须先从matrix复制它
编辑:现在尝试了相同的ints,但它的发生完全相同。我想这不会发生在值类型上
BigNumDec是不可变的。值类型仍然发生这种情况的原因是因为您使用的是一个数组数组。您正在浅层复制“外部”数组,它只复制对两个“内部”数组的引用
您还没有显示
BigNumDec
是否是不可变的(我希望是这样),但是如果是,您只需深度复制数组就可以了。或者,您是否可以使用矩形数组而不是锯齿状数组?如果是这样,一份简单的副本就足够了。请注意,矩形阵列会对性能产生影响-值得进行测试,看看这是否会给您带来问题。您可以获得更好的引用局部性,但实际的数组访问速度没有那么快。值类型仍然存在这种情况的原因是因为您使用的是数组数组。您正在浅层复制“外部”数组,它只复制对两个“内部”数组的引用
您还没有显示
BigNumDec
是否是不可变的(我希望是这样),但是如果是,您只需深度复制数组就可以了。或者,您是否可以使用矩形数组而不是锯齿状数组?如果是这样,一份简单的副本就足够了。请注意,矩形阵列会对性能产生影响-值得进行测试,看看这是否会给您带来问题。您可以获得更好的引用位置,但实际的数组访问速度没有那么快。问题在于您初始化BigNumDec数组时,正在创建BigNumDec对象的一维数组。[0] = { 1, 2 }, [1] = { 3. 4 }. 然后,您将有效地复制这些对象的引用,而不是它们的内容,因此值将继续更改
将您的初始化更改为:
BigNumDec[,] matrix = new BigNumDec[,] {
{ 1, 2 },
{ 3, 4 }
};
问题在于初始化BigNumDec数组时,您正在创建BigNumDec对象的一维数组。[0] = { 1, 2 }, [1] = { 3. 4 }. 然后,您将有效地复制这些对象的引用,而不是它们的内容,因此值将继续更改 将您的初始化更改为:
BigNumDec[,] matrix = new BigNumDec[,] {
{ 1, 2 },
{ 3, 4 }
};
如果对象可序列化,则可以使用序列化实现深度复制。它不是很有效(从性能上看),但很简单
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
}
(正如在这里的其他答案中所说,如果您可以移动到二维数组而不是锯齿状数组,您将得到更好的解决方案)如果您的对象是可序列化的,您可以使用序列化实现深度复制。它不是很有效(从性能上看),但很简单
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
}
(正如在这里的其他答案中所说,如果您可以移动到二维数组而不是锯齿数组,您将得到更好的解决方案)使用简单的for,它可以很好地处理int。它能与BigNumDec很好地合作吗?我会说不。如果可能的话,你能解释一下为什么不可变或不可变在这里会有不同吗?当它检测到我想要更改值时,是否会在幕后创建一个新值?使用简单的for,它可以很好地处理int。它能与BigNumDec很好地合作吗?我会说不。如果可能的话,你能解释一下为什么不可变或不可变在这里会有不同吗?当它检测到我想要更改值时,是否会在幕后创建一个新值?