我正在尝试实施深度克隆功能,并且已经提出了一些问题:
我正在修改以下代码: https://stackoverflow.com/a/11308879/2598770
目前我面临的问题是,我的原始列表也会被“复制”对象修改,而不是只修改克隆对象,正如前面第二个问题(Array, List, IEnumerable, CustomList class cast to one and iterate threw them)所推荐的那样。我更改了以下代码:
//Code directly from source
var cloneObject = CloneMethod.Invoke(originalObject, null);
if (typeToReflect.IsArray)
{
var arrayType = typeToReflect.GetElementType();
if (IsPrimitive(arrayType) == false)
{
Array clonedArray = (Array)cloneObject;
clonedArray.ForEach((array, indices) => array.SetValue(InternalCopy(clonedArray.GetValue(indices), visited), indices));
}
}
对于也处理IList而不仅仅是数组的版本:
var cloneObject = CloneMethod.Invoke(originalObject, null);
if (cloneObject is IList)
{
if (typeToReflect.GetGenericArguments().Any())
{
var arrayType = typeToReflect.GenericTypeArguments[0];
if (IsPrimitive(arrayType) == false)
{
var clonedArray = (IList)cloneObject;
if (clonedArray.IsReadOnly == false)
for (var i = 0; i < clonedArray.Count; i++)
{
var originalListEntry = clonedArray[i];
var clonedListEntry = InternalCopy(originalListEntry, visited);
clonedArray[i] = clonedListEntry;
}
}
}
}
但在clonedArray[i] = clonedListEntry;
行,它不仅仅改变了clonedArray,还改变了originalObject
。
如何防止这种情况,以便只在clonedArray上设置clonedListEntry?
答案 0 :(得分:1)
您需要创建一个新容器,而不是仅仅获取对cloneObject
的引用。例如:
var existingList = (IList)cloneObject;
var clonedArray = Array.CreateInstance(arrayType, existingList.Count);
然后,您可以继续填充clonedArray
。在现有代码中,clonedArray
只是对原始列表的引用(它甚至不能保证是一个数组!),因此对其进行的任何更改都会反映到原始列表中。