0

I am implementing a hierarchy of classes that use .NET's built in serialization. Due to the nature of most of these classes and the way .NET handles deserialization with a graph deserializer, I need to store temporary data somewhere and wait for it to be fully deserialized.

My classes all currently include something similar to the following:

class Example : ISerializable
{
  private readonly dynamic _serialData = new ExpandoObject();

  public ulong Id { get; private set; }
  public string[] Strings { get; private set; }

  protected Example( SerializationInfo info, StreamingContext context )
  {
    _serialData.Id = info.GetValue( nameof( Id ), typeof( ulong ) );
    _serialData.Strings = info.GetValue( nameof( Strings ), typeof( string[] ) );
  }

  public void GetObjectData( SerializationInfo info, StreamingContext context )
  {
    info.AddValue( nameof( Id ), Id );
    info.AddValue( nameof( Strings ), Strings );
  }

  [OnDeserialized]
  private void OnDeserialized( StreamingContext context )
  {
    Id = _serialData.Id;
    Strings = _serialData.Strings;
  }

}

I realize that the OnDeserialized() method can sometimes be redundant for primitives and other non-enumerable types, but I am trying to keep everything uniform with the more complex classes that have references to child classes and so on.

With that, here's my question:

I currently store the temporary data in the _serialData field. Once it is deserialized, there is no need for this field anymore. I could easily just clear the field once deserialization is complete, but I would much rather have it stored somewhere as a scoped variable that is garbage collected when it is no longer needed.

I see that the StreamingContext is passed along with the serialization constructor and methods, but I don't really understand what it is used for, and I don't see any way to store temporary data in it.

Is there a way I can avoid having _serialData as a class field entirely?

w0f
  • 908
  • 9
  • 23
  • *.NET's built in serialization* - are you referring to `BinaryFormatter`? – dbc Sep 21 '18 at 19:19
  • @dbc Yes, my objects implement `ISerializable` and I am currently using BinaryFormatter to serialize and deserialize the data. – w0f Sep 21 '18 at 20:02
  • Then you could use a serialization surrogate. See e.g. [Is it possible to do .NET binary serialization of an object when you don't have the source code of the class?](https://stackoverflow.com/a/16121346). – dbc Sep 21 '18 at 20:05

1 Answers1

1

The first and easiest thing that comes to mind is a static ConditionalWeakTable (See docs). You can also periodically check the table to see which objects are still alive, and remove the garbage collected objects from the table. Or in the destructor of the objects, get them to remove themselves from the table.

Michal Ciechan
  • 13,492
  • 11
  • 76
  • 118