【问题标题】:Maintain object references through Serialize/Deserialize通过序列化/反序列化维护对象引用
【发布时间】:2009-01-23 15:00:41
【问题描述】:

在序列化时,我只想将一个对象序列化一次,然后对该对象的任何引用都应序列化为对该对象的引用。这是因为,当我稍后反序列化对象时,我想维护这些引用。为了说明我的目标,下面的代码应该输出“序列化后: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; }
}

【问题讨论】:

    标签: .net serialization


    【解决方案1】:

    如果您使用的是 .NET 3 或更高版本,则应使用 DataContractSerializer 并将 PreserveObjectReferences 设置为 true

    【讨论】:

    • 我只是尝试这样做,但它不起作用,因为它是只读属性。我在这里错过了什么?
    【解决方案2】:

    您必须通过提供对象标识符而不是对象引用来做到这一点。

    对象的引用本质上是它的指针。由于您不能在安全代码中直接操作指针,因此必须为对象指定其他唯一名称。

    【讨论】:

      【解决方案3】:

      不确定这是否是你想听到的……但让我们想想你想要做什么。

      只有在以下情况下才需要序列化对象: a)您想将其存储在某个地方,以便后者检索信息。 b) 您想将对象发送到另一个应用程序。

      引用只不过是指向对象所在位置的指针。因此,无论哪种情况,您都无法访问内存,因为在 a) 它是为您的应用程序保留的,而在 b) 它是另一台机器,甚至不存在。

      http://en.csharp-online.net/Glossary:Definition_-_Reference_type

      【讨论】:

        【解决方案4】:

        您的代码示例无法正常工作,因为 XmlSerializer 不保存参考信息,在序列化过程中,它只会将 obj 的数据写入流两次,这意味着当您反序列化时,它将读取 obj 的数据为两个不同的实例,它无法知道它们在序列化时引用了同一个实例。使用前面提到的 DataContractSerializer 应该可以满足您的需求,但请注意它使用非标准 xml (见:http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx

        【讨论】:

          猜你喜欢
          • 2016-05-11
          • 2013-11-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-14
          • 1970-01-01
          相关资源
          最近更新 更多