.NET serialization issue with static field reference

I am using SerializableAttribute

to write an object jack

to disk. The object has a member department

that refers to a static field of accounts

another class department

. When deserializing, I found that the item of the department

deserialized object no longer points to the same object as the static field accounts

, but now points to another identical copy.

All classes and objects are reference types. How do I get around this?

(Sorry for the long code post.)

#include "stdafx.h"

using namespace System;
using namespace System::IO;
using namespace System::Runtime::Serialization;
using namespace System::Runtime::Serialization::Formatters::Binary;

[Serializable]
ref class Department {
    static Department(){ accounts = gcnew Department(L"Accounts"); }
public:
    static Department ^accounts;
    // similarly other departments come here...

    String ^name;
    Department(String ^name) : name(name) { }
};

[Serializable]
ref class Employee {
public:
    String ^name;
    Department ^department;

    Employee(String ^name, Department ^department) : name(name),
        department(department) { }

};

int main(array<System::String ^> ^args)
{
    Employee ^jack;
    IFormatter ^formatter = gcnew BinaryFormatter();

    String ^option = Console::ReadLine();
    if(option == L"read"){
        Stream ^stream = gcnew FileStream(L"dingdong.bin", FileMode::Open,
            FileAccess::Read, FileShare::Read);
        jack = (Employee^) formatter->Deserialize(stream);

        if(jack->department != Department::accounts)
            Console::WriteLine(L"Different objects");
        else
            Console::WriteLine(L"The same object");
        stream->Close();
        Console::ReadLine();
    }
    else {
        jack = gcnew Employee(L"Jack", Department::accounts);
        Stream ^stream = gcnew FileStream(L"dingdong.bin", FileMode::Create,
            FileAccess::Write, FileShare::None);
        formatter->Serialize(stream, jack);
        stream->Close();
    }

    return 0;
}

      

Edit: Code of added code

+1


a source to share


3 answers


In the simplest case, [NonSerialized]

s IDeserializationCallback

to restore links will do the trick. Instead, you can serialize the department code. Typically, if you need to serialize such single-user objects, you can manually serialize the associated object and replace the "reference" object that implements, IObjectReference

or perhaps use serialization surrogates instead of manual serialization to replace the "reference" object.



PS: in general, I would not recommend using the default binary serialization for anything serious because of the various assembly-binding and versioning issues it tends to produce. In short, serialization is complex and cannot be simplified.

+2


a source


I don't think you are doing this. When you serialize a serialized copy of the current f

static field value . When this is deserialized, an object of the appropriate type is created and its values ​​are hydrated from the serialized data. They can be reference types, but serialization is about passing the values ​​of objects between A and B, not their references.



You save the disk. How do you even know that f

its static field will still be in scope when booting from disk and deserializing?

+1


a source


If you look at the [NonSerialized] attribute documentation, I think you will find this example here.


Ok, now that you've posted the code, the problem becomes clearer. You must allocate the static part of the Department class into a class Departments

. The list or enumeration of departments has nothing to do with the individual objects of the Department.

0


a source







All Articles