我的程序中有三维数组。我想在其中调试值,并将此数组放入另一个数组中,我希望在其中找到差异。
我试过了:
Weights weights = new Weights(); // init inside
List<Weights> weightsDebug = new List<Weigts>();
weightsDebug.Add(weights); // I'd put first weigths into the list
for(int i = 0; i < 100; i++) {
// do some bad things with weights;
weightsDebug.Add(weights);
}
之后,我在weigthsDebug的所有99个元素中的权重值都相同。我试图调试,我意识到,weigts数组正在改变。我知道问题在于引用(按链接复制,而不是按值复制) - 所有推送到weightsDebug
数组元素都与主循环中的weights
链接。
我搜索了一下,发现了一些如何复制1维数组的方法。我接下来尝试了:
我在我的Weights课程中添加了Clone方法:
double[][][] values;
public Weights Clone() {
Weights clone = new Weights();
clone.values = (double[][][]) this.values.Clone();
return clone;
}
public Weights()
{
Console.WriteLine("Constructor WITHOUT arguments fired");
}
现在我在复制权重时这样做:
Weights weights = new Weights(); // init inside
List<Weights> weightsDebug = new List<Weigts>();
weightsDebug.Add(weights); // I'd put first weigths into the list
for(int i = 0; i < 100; i++) {
// do some bad things with weights;
Weights weightsClone = weights.Clone();
weightsDebug.Add(weightsClone);
}
我仍然在整个调试阵列中获得最后更改的值。我怎么纠正它?
答案 0 :(得分:2)
您真正在寻找的是深度克隆,而不是您正在实施的当前浅层克隆。
很久以前,我们意识到通过创建类Serializable,我们可以使用.Net serialization类来快速,轻松,正确地对任何对象进行深度克隆。
以下是我们用于此深度克隆的方法(还有一个使用DataContractSerializer的SilverLight变体):
/// <summary>
/// This method clones all of the items and serializable properties of the current collection by
/// serializing the current object to memory, then deserializing it as a new object. This will
/// ensure that all references are cleaned up.
/// </summary>
/// <returns></returns>
/// <remarks></remarks>
public T CreateSerializedCopy<T>(T oRecordToCopy)
{
// Exceptions are handled by the caller
if (oRecordToCopy == null)
{
return default(T);
}
if (!oRecordToCopy.GetType().IsSerializable)
{
throw new ArgumentException(oRecordToCopy.GetType().ToString() + " is not serializable");
}
var oFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
using (var oStream = new MemoryStream())
{
oFormatter.Serialize(oStream, oRecordToCopy);
oStream.Position = 0;
return (T)oFormatter.Deserialize(oStream);
}
}
要使用此功能,请首先确保使用Serializable属性标记Weights类:
[Serializable]
public class Weights
然后你可以根据需要克隆:
var weights = new List<Weights>();
weights.Add(new Weights());
var debugWeights = CreateSerializedCopy<List<Weights>>(weights);
if (debugWeights[0] == weights[0])
{
System.Diagnostics.Debug.WriteLine("Did not serialize correctly");
}
答案 1 :(得分:1)
这里的问题是你没有一个真正的多维数组,只有一个对象。你有一个&#34;锯齿状的&#34;多维数组,其中对象实际上是数组数组的数组。这意味着要克隆对象,您需要做更多的工作:
clone.values = new double[values.Length][][];
for (int i = 0; i < values.Length; i++)
{
clone.values[i] = new double[values[i].Length][];
for (int j = 0; j < values[i].Length; j++)
{
clone.values[i][j] = (double[])values[i][j].Clone();
}
}