【问题标题】:DeepClone issue with Arrays阵列的 DeepClone 问题
【发布时间】:2014-01-08 11:26:29
【问题描述】:

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

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

我怎样才能防止这种情况,让 clonedListEntry 只在 clonedArray 上设置?

【问题讨论】:

  • 您是否正在重新发明另一个自动映射器?
  • @Dennis 不要这么想,我只是想要一个我的对象的简单副本而已。

标签: c# list clone


【解决方案1】:

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

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

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

【讨论】:

  • 但这不应该已经通过var cloneObject = CloneMethod.Invoke(originalObject, null); 行完成了吗?
  • @RandRandom:我真的不知道,因为我没有看到任何地方的实现。但是问题描述还不足以证明它不会像看起来那样克隆吗?
  • 这里有源代码的直接链接raw.github.com/Burtsev-Alexey/net-object-deep-copy/master/…(来自帖子:stackoverflow.com/a/11308879/2598770),CloneMethod 执行以下操作private static readonly MethodInfo CloneMethod = typeof(Object).GetMethod("MemberwiseClone", BindingFlags.NonPublic | BindingFlags.Instance);
  • @RandRandom: MemberwiseClone is documented 对其输入进行副本:“如果字段是引用类型,则复制引用但引用对象不是;因此,原始对象及其克隆引用同一个对象。"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-12
  • 2011-08-21
  • 1970-01-01
相关资源
最近更新 更多