.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
a source to share
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.
a source to share
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?
a source to share
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.
a source to share