Custom equality comparer for `BinaryFormatter`

54 Views Asked by At

TL;DR;

My custom [Serializable] class overrides GetHashCode and Equals, so multiple distinct objects can be "equal", and it looks like BinaryFormatter calls OnSerialized only once, but calls OnDeserialized twice when two equal but distinct (ReferenceEquals == false) objects exist in the graph.

What can I do to ensure that for every call to [OnSerialized] method [OnDeserialized] method is called exactly once provided I want to keep my GetHashCode and Equals implementations?

Ideally, I would like to instruct BinaryFormatter to use my custom implementation of IEqualityComparer for my custom class so that it would not try to "merge" distinct but equal instances.

Background

The class wraps a refcounted unmanaged handle, that is passed across app domains using BinaryFormatter. To keep the refcount in sync with alive .NET instances, I increase it by 1 in [OnSerialized] handler, assuming the object will be deserialized exactly once, which is violated in the scenario above (the serialized bits are discarded after deserialization).

1

There are 1 best solutions below

0
LOST On

Implementing ISerializable instead of using [OnSerialized] attribute works: GetObjectData gets called for each distinct object even if they are equal by Equals + GetHashCode.

Downsides are:

  1. It is probably slower
  2. Now all types deriving from the wrapper must have a deserializing constructor with signature .ctor(SerializationInfo info, StreamingContext context)