Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 深度复制引用类型_C#_.net - Fatal编程技术网

C# 深度复制引用类型

C# 深度复制引用类型,c#,.net,C#,.net,我正在使用一个名为BigNumDesc的类,它表示一个数字。我有一个参差不齐的数字数组,代表一个矩阵。 我首先以以下方式声明此矩阵: BigNumDec[][] matrix = new BigNumDec[][] { new BigNumDec[] { 1, 2 }, new BigNumDec[] { 3, 4 } }; 现在,我想调用这个方法: static BigNumDec[][] GetStrictlyUpperTriangle(Bi

我正在使用一个名为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,所以我必须先从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很好地合作吗?我会说不。如果可能的话,你能解释一下为什么不可变或不可变在这里会有不同吗?当它检测到我想要更改值时,是否会在幕后创建一个新值?