I’m using SerializableAttribute to write an object jack to disk. The object has a member department which references a static field accounts of another class Department. On deserializing, I find that the member department of the 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 involved are reference types. How do I get around this?
(Sorry about 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: Added example code
In the simplest case,
[NonSerialized]withIDeserializationCallbackto restore the reference will do the trick. You can serialize a department code instead. Generally, if you need to serialize such singleton-like objects, you can serialize the referring object manually and substitute a «reference» object, which implementsIObjectReference, or, possibly, use serialization surrogates instead of manual serialization to substitute the «reference» object.PS: generally, I wouldn’t recommend using default binary serialization for anything serious, because of various assembly-binding and versioning problems it tends to produce. In short, serialization is difficult, and cannot be simplified much.