.net中DataContract属性和Serializable属性之间的区别

我正在尝试使用以下方法创建对象的深层克隆。

public static T DeepClone(this T target) { using (MemoryStream stream = new MemoryStream()) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, target); stream.Position = 0; return (T)formatter.Deserialize(stream); } } 

该方法需要一个Serialized对象,即一个具有“Serializable”属性的类的对象。 我有一个类,它具有属性“DataContract”,但该方法不使用此属性。 我认为“DataContract”也是一种序列化器,但可能与“Serializable”不同。

有人可以给我两者的区别吗? 另外请告诉我是否可以创建一个只有1个属性的对象的深度克隆,它可以完成“DataContract”和“Serializable”属性的工作,也可能是创建深度克隆的不同方式?

请帮忙!

BinaryFormatter需要Serializable才能工作。

DataContractDataMember属性与DataContractSerializer一起使用。

您可以使用两个序列化程序的属性来装饰类。

DataContract用于WCF,因此.NET 3.0+。 在.net 2.0或更低版本中,没有DataContract, DataMember属性,只有Serializable

正如Oded所说,如果你想使用BinaryFormatter,你必须使用Serializable来装饰类型。

我曾经通过Reflection对对象结构进行了一些检查,以找到反序列化所需的所有程序集,并将它们串行化以进行自举。

通过一些工作,可以构建类似的深度复制方法。 基本上你需要一个递归方法,沿着Dictionary来检测循环引用。 在方法内部,您将检查所有字段,如下所示:

 private void InspectRecursively(object input, Dictionary processedObjects) { if ((input != null) && !processedObjects.ContainsKey(input)) { processedObjects.Add(input, true); List 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)等设置每个字段

但是,此实现不支持已注册的事件处理程序,这也是反序列化所支持的事件。 此外,如果其类的构造函数需要初始化除了设置所有字段之外的任何内容,那么层次结构中的每个对象都将被破坏。 最后一点仅适用于序列化,如果类具有相应的实现,例如标记为[OnDeserialized]方法,则实现ISerializable ,….