数组的DeepClone问题

时间:2014-01-08 11:26:29

标签: c# list clone

我正在尝试实施深度克隆功能,并且已经提出了一些问题:

我正在修改以下代码: 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?

1 个答案:

答案 0 :(得分:1)

您需要创建一个新容器,而不是仅仅获取对cloneObject的引用。例如:

var existingList = (IList)cloneObject;
var clonedArray = Array.CreateInstance(arrayType, existingList.Count);

然后,您可以继续填充clonedArray。在现有代码中,clonedArray只是对原始列表的引用(它甚至不能保证是一个数组!),因此对其进行的任何更改都会反映到原始列表中。