Question

Can I avoid adding additional fields to a class to store data which is needed only for deserialization/serialization?

Suppose I have some class:

[Serializable]
class MyClass {
      [NonSerialized]
      NonSerializableDataType myField;

      SomeOtherDataType serializableTemporaryData;

      [OnSerializing]
      OnSerializing (StreamingContext context) {
          // build serializableTemporaryData from myField
      }

      [OnDeserialized]
      void OnDeserialized (StreamingContext context) {
         // build myField from serializableTemporaryData
      }
}

Is there any way to avoid having the serializableTemporaryData field in each object of MyClass? Can I, for example, make it static (possibly by changing my On... methods)?

Constraint: I cannot change the implementation of NonSerializableDataType.

Example: Suppose myField contains a handle to a resource. Then, on serialization, I must store some information on how to acquire the resource after de-serialization, but I cannot store the handle itself. If I wrap the handle into another class, then I have just shifted the problem to the wrapper class -- I would ask the very same question for the wrapper class then.

Was it helpful?

Solution

If you need to control the serialization process, you should implement the ISerialization interface.

[Serializable]
public class MyClass: ISerializable
{
    // As you are in control of serialization process now
    // [Serialized] and [NonSerialized] attributes are no longer required
    private NonSerializableDataType myField;

    public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        // Create and populate your SomeOtherDataType local variable here, then push it into info variable
        // Or even better, dont create SomeOtherDataType, just put additional serialization data into info variable, for example:
        info.AddValue("URL", "http://this.way.com");
    }

    protected MyClass(SerializationInfo info, StreamingContext context)
    {
        // Dont forget to define constructor for deserialization purpose

        this.myField = new NonSerializableDataType(loadFromURL: (string)info.GetValue("URL", typeof(string)));
    }
}

No additional class just for serialization data, no fields pollution. The only potential problem is to watch for any serializable data derived from this class (overwrite GetObjectData(...) if needed).

More info: MSDN ISerializable

OTHER TIPS

There is a concept of serialization surrogates which might help you to overcome the difficulty with SomeNonSerializableType, since it was designed exactly for this reason.. However, this requires that you have the possibility to configure the serialization surrogates, when the formatter is created. Otherwise, you will need to customize the serialization process by implementing ISerializable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top