How to serialize an object which refer another object?

  • Thread starter Thread starter Jerry
  • Start date Start date
J

Jerry

Hi,

I have a class like the following:
class A {
private B _b;

A (B b) {
_b = b;
}
...
public B B {
get { return _b; }
}
}

and:
class B {
...
}

How to serialize an A object and B object? Maybe another serialzied
object C has
a B reference also.

Jerry
 
Hi Jerry,

In the code below, notice that I used the Serializable attribute on the
types I want to serialize. Also, when I performed the serialization, I did
it on the A type, which was the root of the graph. Notice that after
serialization and deserialization that the B type that the A type references
is deserialized properly because the A type holds a reference to it.

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable]
class A
{
private B _b;

public A (B b)
{
_b = b;
}

public B B
{
get { return _b; }
}
}

[Serializable]
class B
{
public string SomeVal;
}

class Test
{
static void Main()
{
B b = new B();
b.SomeVal = "I'm a B";
A a1 = new A(b);

MemoryStream memStr = null;

try
{
memStr = new MemoryStream();

BinaryFormatter binFmt = new BinaryFormatter();

binFmt.Serialize(memStr, a1);

memStr.Position = 0;

A a2 = (A)binFmt.Deserialize(memStr);

Console.WriteLine(a2.B.SomeVal);
}
finally
{
if (memStr != null)
{
memStr.Close();
}
}

Console.ReadLine();
}
}


Joe
 
Hi Joe,

Thank you for your help. But I have another question. If I have two
object a1 and a2, the
B property of them is the same object b; e.g:
B b = new B();
A a1 = new A(b);
A a2 = new A(b);

If I serialize them and get object d_b1, d_a1, d_a2 by deserialize. d_a1.B
would not equal d_a2.B.
Acutally, I want get them same reference for d_a1.B and d_a2.B. How to do
it?

Jerry

Joe Mayo said:
Hi Jerry,

In the code below, notice that I used the Serializable attribute on the
types I want to serialize. Also, when I performed the serialization, I did
it on the A type, which was the root of the graph. Notice that after
serialization and deserialization that the B type that the A type references
is deserialized properly because the A type holds a reference to it.

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable]
class A
{
private B _b;

public A (B b)
{
_b = b;
}

public B B
{
get { return _b; }
}
}

[Serializable]
class B
{
public string SomeVal;
}

class Test
{
static void Main()
{
B b = new B();
b.SomeVal = "I'm a B";
A a1 = new A(b);

MemoryStream memStr = null;

try
{
memStr = new MemoryStream();

BinaryFormatter binFmt = new BinaryFormatter();

binFmt.Serialize(memStr, a1);

memStr.Position = 0;

A a2 = (A)binFmt.Deserialize(memStr);

Console.WriteLine(a2.B.SomeVal);
}
finally
{
if (memStr != null)
{
memStr.Close();
}
}

Console.ReadLine();
}
}


Joe
--
http://www.csharp-station.com

Jerry said:
Hi,

I have a class like the following:
class A {
private B _b;

A (B b) {
_b = b;
}
...
public B B {
get { return _b; }
}
}

and:
class B {
...
}

How to serialize an A object and B object? Maybe another serialzied
object C has
a B reference also.

Jerry
 
It should work if you can serialize them both in the same graph:

binFmt.Serialize(memStr, new A[] { a1, a2 });
Console.WriteLine(Object.ReferenceEquals(a1.B, a2.B));

memStr.Position = 0;

A[] arr = (A[])binFmt.Deserialize(memStr);

Console.WriteLine(Object.ReferenceEquals(arr[0].B, arr[1].B));

Otherwise, there isn't a way to know that a1 and a2, which were serialized
separately, originally refered to the same b.

Another thought is to implement ISerializable. Make sure every object has a
unique ID (i.e. GUID) when you serialize it and create your own mechanism to
rebuild references based on object ID.

Joe
--
http://www.csharp-station.com

Jerry said:
Hi Joe,

Thank you for your help. But I have another question. If I have two
object a1 and a2, the
B property of them is the same object b; e.g:
B b = new B();
A a1 = new A(b);
A a2 = new A(b);

If I serialize them and get object d_b1, d_a1, d_a2 by deserialize. d_a1.B
would not equal d_a2.B.
Acutally, I want get them same reference for d_a1.B and d_a2.B. How to do
it?

Jerry

Joe Mayo said:
Hi Jerry,

In the code below, notice that I used the Serializable attribute on the
types I want to serialize. Also, when I performed the serialization, I did
it on the A type, which was the root of the graph. Notice that after
serialization and deserialization that the B type that the A type references
is deserialized properly because the A type holds a reference to it.

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable]
class A
{
private B _b;

public A (B b)
{
_b = b;
}

public B B
{
get { return _b; }
}
}

[Serializable]
class B
{
public string SomeVal;
}

class Test
{
static void Main()
{
B b = new B();
b.SomeVal = "I'm a B";
A a1 = new A(b);

MemoryStream memStr = null;

try
{
memStr = new MemoryStream();

BinaryFormatter binFmt = new BinaryFormatter();

binFmt.Serialize(memStr, a1);

memStr.Position = 0;

A a2 = (A)binFmt.Deserialize(memStr);

Console.WriteLine(a2.B.SomeVal);
}
finally
{
if (memStr != null)
{
memStr.Close();
}
}

Console.ReadLine();
}
}


Joe
--
http://www.csharp-station.com

Jerry said:
Hi,

I have a class like the following:
class A {
private B _b;

A (B b) {
_b = b;
}
...
public B B {
get { return _b; }
}
}

and:
class B {
...
}

How to serialize an A object and B object? Maybe another serialzied
object C has
a B reference also.

Jerry
 
Back
Top