首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带引用静态字段的.NET序列化问题

带引用静态字段的.NET序列化问题
EN

Stack Overflow用户
提问于 2009-05-21 14:08:01
回答 3查看 339关注 0票数 1

我使用SerializableAttribute将对象jack写入磁盘。该对象有一个成员department,它引用另一个类Department的静态字段accounts。在反序列化时,我发现反序列化对象的成员department不再指向与静态字段accounts相同的对象,而是指向另一个相同的副本。

所涉及的所有类和对象都是引用类型。我怎么才能避开这一切?

(很抱歉,长代码的帖子。)

代码语言:javascript
运行
复制
#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;
}

编辑:添加了示例代码

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-05-21 14:36:22

在最简单的情况下,使用[NonSerialized]IDeserializationCallback来恢复引用就可以了。您可以代替序列化部门代码。通常,如果您需要序列化这类类单例对象,您可以使用手动序列化引用对象,并替换引用对象。 (它实现了IObjectReference ),或者可能使用序列化代理代替手动序列化来替代引用对象。

PS:通常,我不建议对任何严重的问题使用默认的二进制序列化,因为它往往会产生各种程序集绑定和版本控制问题。简而言之,序列化是很困难的,不能简化很多。

票数 2
EN

Stack Overflow用户

发布于 2009-05-21 14:11:16

我不认为你知道。序列化时,f静态字段当前值的序列化副本。当反序列化时,将创建相关类型的对象,并将其值从序列化数据中水合物化。这些可能是引用类型,但序列化是在A和B之间传递对象的值,而不是它们的引用。

您正在保存到磁盘。当您从磁盘加载并反序列化时,您如何知道f及其静态字段仍然在范围内?

票数 1
EN

Stack Overflow用户

发布于 2009-05-21 14:11:41

如果您查找NonSerialized属性文档,我认为您会在那里找到这个示例。

好了,既然你已经发布了代码,问题就变得更清楚了。您应该将Department类的静态部分分离为一个Departments类。部门的列表或枚举与单个Department对象无关。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/893111

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档