Fie avem o clasă A:
Code: Select all
ref class A
{
public:
int x;
A()
{
x = 1234;
}
};
Code: Select all
[Serializable]
ref class B
{
public:
int y;
[NonSerialized]
A a;
};
Să declarăm o variabilă de tip B şi să o serializăm într-un flux. Pentru simplitate vom folosi unul alocat în memorie:
Code: Select all
B ^ b = gcnew B;
b->y = 5678;
// Serializare
MemoryStream ^ ms = gcnew MemoryStream;
BinaryFormatter ^ bf = gcnew BinaryFormatter;
bf->Serialize(ms, b);
Code: Select all
// Deserializare
ms->Position = 0;
b = (B^)bf->Deserialize(ms);
Code: Select all
int y = b->y; // 5678 -- corect
int x = b->a.x; // eroare: NullReferenceException
Deoarece membrul a este neserializabil, ne aşteptăm ca după deserializare valoarea acestuia să fie cea implicită, definită de constructor. Însă încercarea de citire a membrului a eşuează -- se generează excepţia NullReferenceException. Evident nu b este cel care e nul. Este vorba de acea referinţă ascunsă generată de compilator pentru membrul a. Şi nici nu este posibilă refacerea manuală a membrului a, deoarece expresiile b->a = gcnew A şi b->a = *gcnew A sînt eronate.
Prin urmare membrii neserializabili avînd semantica de stivă se pierd în urma operaţiilor de deserializare, făcînd imposibilă utilizarea ulterioară a obiectelor deserializate.
Sursa: http://social.msdn.microsoft.com/Forums ... 63e133361f.
Next FAQ >>