序列化时,我想只对序列化一个对象,然后对该对象的任何引用都应序列化为对象的引用。这是因为,当我稍后反序列化对象时,我想保留这些引用。为了说明我的目标,下面的代码应该输出“After Serialization:true”。
class Program
{
static void Main(string[] args)
{
MyObject obj = new MyObject() { Name = "obj" };
MyObject[] myObjs = new MyObject[]
{
obj, obj
};
Console.WriteLine("Object Refs Equal?");
Console.WriteLine(string.Format("Before Serialization: {0}",
object.ReferenceEquals(myObjs[0], myObjs[1])));
XmlSerializer toXml = new XmlSerializer(typeof(MyObject[]));
using (FileStream toFile = File.Create(@"C:\foo.xml"))
{
toXml.Serialize(toFile, myObjs);
}
XmlSerializer fromXml = new XmlSerializer(typeof(MyObject[]));
using (FileStream fromFile = File.OpenRead(@"C:\foo.xml"))
{
MyObject[] deserialized = (MyObject[])fromXml.Deserialize(fromFile);
Console.WriteLine(string.Format("After Serialization: {0}",
object.ReferenceEquals(deserialized[0], deserialized[1])));
}
Console.ReadLine();
}
}
[Serializable]
public class MyObject
{
public string Name { get; set; }
}
答案 0 :(得分:2)
如果您使用的是.NET 3或更高版本,则应使用DataContractSerializer
并将PreserveObjectReferences
设置为true
。
答案 1 :(得分:0)
您必须通过提供除对象引用之外的对象标识符来实现此目的。
对象的引用本质上是它的指针。由于无法直接在安全代码中操作指针,因此必须为对象提供其他唯一名称。
答案 2 :(得分:0)
不确定这是否是您想要听到的......但是,让我们考虑一下您想要做什么。
您只需要在以下情况下序列化对象: a)您希望将其存储在后者的某个位置以检索信息。 b)您希望将对象发送到另一个应用程序。
引用只不过是指向对象所在位置的指针。所以在任何一种情况下你都无法访问内存,因为a)它是为你的应用程序保留的,而b)它是另一台机器,它甚至不存在。
http://en.csharp-online.net/Glossary:Definition_-_Reference_type
答案 3 :(得分:0)
你的代码示例不能简单地工作,因为XmlSerializer不保存参考信息,在序列化过程中它只会将obj的数据写入流两次,这意味着当你反序列化时它会读取obj的数据为两个不同的实例,它无法知道它们在序列化时引用了同一个实例。使用前面提到的DataContractSerializer应该给你你想要的,但请注意它使用非标准的xml (见:http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx)