我正在使用SerializableAttribute
将对象jack
写入磁盘。该对象有一个成员department
,它引用另一个类accounts
的静态字段Department
。在反序列化时,我发现反序列化对象的成员department
不再指向与静态字段accounts
相同的对象,而是指向另一个相同的副本。
所涉及的所有类和对象都是引用类型。我该如何解决这个问题?
(对不起长码贴子。)
#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;
}
修改:添加了示例代码
答案 0 :(得分:2)
在最简单的情况下,使用[NonSerialized]
IDeserializationCallback
来恢复引用将会起到作用。您可以改为序列化部门代码。通常,如果您需要序列化类似单例的对象,可以serialize the referring object manually and substitute a «reference» object实现IObjectReference
,或者可能使用serialization surrogates而不是手动序列化来替换«reference»对象
PS:一般来说,我不建议对任何严重的事情使用默认的二进制序列化,因为它往往会产生各种程序集绑定和版本控制问题。简而言之,序列化很难,并且不能简化太多。
答案 1 :(得分:1)
我不认为你这样做。序列化时,f
的静态字段的当前值的序列化副本。当反序列化时,将创建相关类型的对象,并从序列化数据中对其值进行水合。这些可能是引用类型,但序列化是关于在A和B之间传输对象的值,而不是它们的引用。
您正在保存到磁盘。当你从磁盘加载并反序列化时,你怎么知道f
及其静态字段仍然在范围内?
答案 2 :(得分:0)
如果你查找[NonSerialized]属性文档,我想你会在那里找到这个例子。
好的,既然您已发布代码,问题就会变得更加清晰。您应该将Department类的静态部分分离为Departments
类。部门的列表或枚举与各个部门对象无关。