我的答案副本:.net 中 DataContract 属性和 Serializable 属性之间的区别
我的回答在这里比那里好得多,尽管上面的问题以:
“......或者也许是创建深度克隆的不同方式?”
我曾经通过反射对对象结构进行了一些检查,以找到反序列化所需的所有程序集,并将它们与引导程序一起序列化。
通过一些工作,您可以构建一种类似的深度复制方法。基本上,您需要一个带有 Dictionary 的递归方法来检测循环引用。在方法中,您检查所有字段,如下所示:
private void InspectRecursively(object input,
Dictionary<object, bool> processedObjects)
{
if ((input != null) && !processedObjects.ContainsKey(input))
{
processedObjects.Add(input, true);
List<FieldInfo> fields = type.GetFields(BindingFlags.Instance |
BindingFlags.Public | BindingFlags.NonPublic );
foreach (FieldInfo field in fields)
{
object nextInput = field.GetValue(input);
if (nextInput is System.Collections.IEnumerable)
{
System.Collections.IEnumerator enumerator = (nextInput as
System.Collections.IEnumerable).GetEnumerator();
while (enumerator.MoveNext())
{
InspectRecursively(enumerator.Current, processedObjects);
}
}
else
{
InspectRecursively(nextInput, processedObjects);
}
}
}
}
为了让它工作,你需要添加一个输出对象和类似的东西System.Runtime.Serialization.FormatterServices.GetUninitializedObject(Type type)
来创建每个字段值的最浅的副本(即使没有复制引用)。最后,您可以使用类似的内容设置每个字段field.SetValue(input, output)
但是,此实现不支持已注册的事件处理程序,反序列化也_un_支持。此外,层次结构中的每个对象都将被破坏,如果其类的构造函数需要初始化任何内容而不是设置所有字段。最后一点仅适用于序列化,如果该类具有相应的实现,例如方法标记[OnDeserialized]
,实现ISerializable
,...。