具有包含基本Model实例的Model实例的深复制模型。 StackOverflow异常

问题描述 投票:2回答:1

好吧,为了开始这个问题,这里有几件事。

  1. 该解决方案不能使用序列化。
  2. 下面列出的代码将在满足以下条件之前起作用:一种。 CopyObjectHierarchyTo被递归调用,并遍历一个对象,该对象包含另一个对象的实例,并且该对象包含父引用的实例。

我正在尝试使用此方法来深度复制任何对象,并避免StackOverflow异常。我了解StackOverflow正在发生,为什么,我需要帮助,以了解如何以编程方式实现此目的以在发生之前对其进行检测。

我不确定这是否可行,但是如果我能够看到引用中包含的对象也包含父引用的实例,那基本上就是我想要实现的。

AKA A类{B类}其中B类包含A类

谢谢您的帮助。

    public static void CopyObjectHierarchyTo(this object sourceObject, object targetObject)
    {
        var objectMap = new Dictionary<object, object>();
        CopyObjectHierarchyTo(sourceObject, targetObject, objectMap);
    }

    private static void CopyObjectHierarchyTo(
        this object sourceObject,
        object targetObject,
        IDictionary<object, object> objectMap)
    {
        try
        {
            if (sourceObject == null)
            {
                throw new ArgumentNullException(
                    "sourceObject",
                    string.Format(CultureInfo.InvariantCulture, "Argument '{0} cannot be null!", "sourceObject"));
            }
            if (targetObject == null)
            {
                throw new ArgumentNullException(
                    "targetObject",
                    string.Format(CultureInfo.InvariantCulture, "Argument '{0} cannot be null!", "targetObject"));
            }
            if (objectMap == null)
            {
                throw new ArgumentNullException(
                    "objectMap",
                    string.Format(CultureInfo.InvariantCulture, "Argument '{0} cannot be null!", "objectMap"));
            }

            if (!objectMap.ContainsKey(sourceObject))
            {
                objectMap.Add(sourceObject, targetObject);
            }

            var targetType = targetObject.GetType();
            var targetProperties = targetType.GetProperties();
            var sourceType = sourceObject.GetType();

            foreach (var targetProp in targetProperties)
            {
                var sourceProp = sourceType.GetProperty(targetProp.Name);
                if (sourceProp == null)
                {
                    continue;
                }

                var sourceValue = sourceProp.GetValue(sourceObject, null);

                if (sourceValue == null)
                {
                    continue;
                }

                object targetValue;
                if (objectMap.TryGetValue(sourceValue, out targetValue))
                {
                    targetProp.SetValue(targetObject, targetValue, null);
                    continue;
                }

                if (targetProp.PropertyType.IsValueType)
                {
                    CopyValueType(sourceObject, targetObject, sourceProp, targetProp);
                }
                else if (sourceProp.PropertyType == typeof(string))
                {
                    CopyString(sourceObject, targetObject, sourceProp, targetProp);
                }
                else if (sourceProp.PropertyType.GetInterfaces().Any(
                    x =>
                    x.IsGenericType &&
                    x.GetGenericTypeDefinition() == typeof(ICollection<>)))
                {
                    if (!targetProp.PropertyType.GetInterfaces().Any(
                        x =>
                        x.IsGenericType &&
                        x.GetGenericTypeDefinition() == typeof(ICollection<>)))
                    {
                        ThrowTypeMismatch(sourceProp.Name, sourceType, targetType);
                    }

                    CopyCollection(sourceObject, targetObject, sourceProp, targetProp, objectMap);
                }
                else
                {
                    targetValue = targetProp.GetValue(targetObject, null)
                                  ?? Activator.CreateInstance(targetProp.PropertyType);

                    if (targetProp.SetMethod == null)
                    {
                        continue;
                    }

                    targetProp.SetValue(targetObject, targetValue, null);
                    sourceValue.CopyObjectHierarchyTo(targetValue, objectMap);
                }
            }
        }
        catch(Exception ex)
        {
        }
    }
c# recursion stack-overflow deep-copy
1个回答
0
投票

@@ Dennis1679感谢您的回答,此类似乎可以解决问题,并解决了我的问题。也要感谢@Erik Philips,因为我相信您也正处在正确的位置上。

© www.soinside.com 2019 - 2024. All rights reserved.