2009-05-21 57 views
1

我正在使用SerializableAttribute將對象jack寫入磁盤。該對象有一個成員department,它引用另一個類Department的靜態字段accounts。在反序列化中,我發現反序列化對象的成員department不再指向與靜態字段accounts相同的對象,但現在指向另一個相同的副本。參考靜態字段的.NET序列化問題

所涉及的所有類和對象都是引用類型。我如何解決這個問題?

(抱歉長後置代號。)

#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; 
} 

編輯:增加了代碼示例

回答

2

在最簡單的情況下,[NonSerialized]IDeserializationCallback恢復參考將做的伎倆。您可以改爲序列化部門代碼。通常,如果需要序列化這種類似單例對象,則可以使用serialize the referring object manually and substitute a «reference» object(它實現IObjectReference),或者可能使用serialization surrogates而不是手動序列化來替換「reference」對象。 PS:通常,我不會推薦使用默認的二進制序列化來處理任何嚴重的事情,因爲它會產生各種組裝綁定和版本控制問題。總之,系列化很難,並且不能簡化太多。

1

我不認爲你做的。當你序列化時,一個當前值爲f的靜態字段的序列化副本。當這是反序列化時,將創建相關類型的對象,並從序列化數據中提取其值。這些可能是引用類型,但序列化是關於在A和B之間傳遞對象的值,而不是它們的引用。

您正在保存到磁盤。當你從磁盤加載並反序列化時,你甚至知道f及其靜態字段仍然在範圍之內?

0

如果你查看[NonSerialized]屬性文檔,我想你會在那裏找到這個例子。


好了,現在你已經發布的代碼,這個問題變得更加清晰。您應該將Department類的靜態部分分爲Departments類。部門列表或枚舉與單個部門對象無關。