Tricky serialization of ISerializable objects in a custom formatter

  • Thread starter Thread starter Joannes Vermorel
  • Start date Start date
J

Joannes Vermorel

I am currently implementing a custom formatter (inherits IFormatter). I
would like to know how am I suppose to handle ISerializable objects ? Indeed
SerializationInfo is not marked as [Serializable] and there is no member to
access its content.

Anybody has an idea?
Joannès
 
Hi,
I am currently implementing a custom formatter (inherits IFormatter). I
would like to know how am I suppose to handle ISerializable objects ? Indeed

Of course you have to handle ISerializable objects!
SerializationInfo is not marked as [Serializable] and there is no member to
access its content.

SerializationInfo isn't supposed to be serialized. The object
is created by the runtime and in turn it will *use* your
Fomatter. Therefore you should inherit from
System.Runtime.Serialization.Formatter.

bye
Rob
 
SerializationInfo isn't supposed to be serialized. The object
is created by the runtime and in turn it will *use* your
Fomatter. Therefore you should inherit from
System.Runtime.Serialization.Formatter.

Yes this is the logical solution, but the problem is that I do not see how I
can set my own formatter to be called by SerializationInfo. Does inheriting
IFormatter or Formatter change anything to the problem?

I have to implement Serialize method (see below).

public void Serialize(Stream stream, object graph)
{
<stuff>
if(someObject.GetType().IsSubClassOf(typeof(ISerialisable))
{
// What I am supposed to do here ?
}
<stuff>
}

What I am supposed to do with this ISerializable object ? One idiotic
solution is to create a BinaryFormatter and to use it to serialize the
object. In this case it would even "fit" my needs. But is there any way
where I do not need to rely on an existing formatter to implement my own ?

Joannès
 
Hi Joannes,
What I am supposed to do with this ISerializable object ? One idiotic
solution is to create a BinaryFormatter and to use it to serialize the
object. In this case it would even "fit" my needs. But is there any way
where I do not need to rely on an existing formatter to implement my own ?

Have a look at

FormatterServices
SerializationInfo.GetEnumerator()
SerializationInfoEnumerator

public void Serialize(Stream stream, object graph)
{
if(someObject.GetType().IsSubClassOf(typeof(ISerialisable))
{
SerializationInfo info = new SerializationInfo(
someObject.GetType(), new FormatterConverter());

((ISerializable)someObject).GetObjectData(info, context);

SerializationInfoEnumerator e = info.GetEnumerator();
while (e.MoveNext) {
// do something with e.Name, e.Value ...
}
}
else { // not ISerializable
MemberInfo[] memberList =
FormatterServices.GetSerializableMember(someObject.GetType());

object[] dataList =
FormatterServices.GetObjectData(someObject, memberList);

for (int i = 0; i < memberList.Length; i++) {
// do something with memberList and dataList
}
}
}

This might not be complete! I never developed a formatter,
just took a look at one. You are supposed to handle ISerialization-
Surrogates too.

bye
Rob
 
FormatterServices
SerializationInfo.GetEnumerator()
SerializationInfoEnumerator

Thanks, that's it! I did not notice this 'GetEnumerator()' method of
'SerializationInfo'.


if(someObjectType.IsSubClassOf(typeof(ISerializable))

The line here above seems not to work. It seems that the SubClassOf does not
check interfaces ? I am using this instead.

if(someObjectType.GetType().GetInterface(
"System.Runtime.Serialization.ISerializable") != null)


Is there a more simple way of checking the ISerializable interface
implementation?

Joannès
 
Hi Joannes,
if(someObjectType.IsSubClassOf(typeof(ISerializable))

The line here above seems not to work. It seems that the SubClassOf does not
check interfaces ? I am using this instead.

I just duplicated your line.
if(someObjectType.GetType().GetInterface(
"System.Runtime.Serialization.ISerializable") != null)


Is there a more simple way of checking the ISerializable interface
implementation?

If you have the object, as in the sample:

if (someObject is ISerializable) {
}

If you have only the type I really don't know.

bye
ROb
 
Back
Top