好的,为了开始这个问题,这里有几件事。
我正在尝试使用此方法来深度复制任何对象,并避免StackOverflow异常。我知道StackOverflow正在发生,为什么,我需要帮助,以了解如何以编程方式实现此目的以在发生之前对其进行检测。
我不确定这是否可行,但是如果我能够看到引用中包含的对象也包含父引用的实例,那基本上就是我想要实现的。
AKA A类{Class 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)
{
}
}