Поддерживать ссылки на объекты через сериализацию / десериализацию - PullRequest
3 голосов
/ 23 января 2009

При сериализации я хотел бы сериализовать объект только один раз, тогда любые ссылки на этот объект должны быть сериализованы как ссылка на объект. Это потому, что когда я позже десериализую объекты, я бы хотел сохранить эти ссылки. Чтобы проиллюстрировать мою цель, приведенный ниже код должен вывести «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; }
}

Ответы [ 4 ]

2 голосов
/ 23 января 2009

Если вы используете .NET 3 или новее, вы должны использовать DataContractSerializer и установить PreserveObjectReferences на true.

0 голосов
/ 23 января 2009

ваш пример кода не будет работать просто потому, что XmlSerializer не сохраняет справочную информацию, в процессе сериализации он просто дважды записывает данные для obj в поток, это означает, что при десериализации он будет читать данные для obj два разных экземпляра, он не может знать, что они ссылались на один и тот же экземпляр во время сериализации. использование DataContractSerializer, упомянутого выше, должно дать вам то, что вы хотите, но обратите внимание, что он использует нестандартный XML (см .: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx)

0 голосов
/ 23 января 2009

Не уверен, что это то, что вы хотели бы услышать ... Но давайте просто подумаем о том, что вы пытаетесь сделать.

Вам необходимо сериализовать объект только когда: а) Вы хотите сохранить его где-нибудь позже при получении информации. б) Вы хотите отправить объект в другое приложение.

Ссылка - это не более чем указатель на то, где находится объект. Так что в любом случае вы просто не можете получить доступ к памяти, потому что в а) она зарезервирована для вашего приложения, а в б) это другая машина и ее даже не существует.

http://en.csharp -online.net / Глоссарий: Определение _-_ Reference_type

0 голосов
/ 23 января 2009

Вы должны будете сделать это, указав идентификаторы объектов, отличные от их ссылки на объект.

Ссылка на объект по сути является указателем. Поскольку вы не можете манипулировать указателями непосредственно в безопасном коде, необходимо дать объекту другое уникальное имя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...