简体   繁体   English

`BinaryFormatter` 的自定义相等比较器

[英]Custom equality comparer for `BinaryFormatter`

TL;DR; TL;博士;

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.我的自定义[Serializable] class 覆盖GetHashCodeEquals ,因此多个不同的对象可以“相等”,看起来BinaryFormatter只调用一次OnSerialized ,但是当两个相等但不同的( ReferenceEquals == false )对象存在时调用OnDeserialized两次图形。

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?如果我想保留我的GetHashCodeEquals实现,我能做些什么来确保每次调用[OnSerialized]方法[OnDeserialized]方法只被调用一次?

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.理想情况下,我想指示BinaryFormatter为我的自定义 class 使用我自定义的IEqualityComparer实现,这样它就不会尝试“合并”不同但相等的实例。

Background背景

The class wraps a refcounted unmanaged handle, that is passed across app domains using BinaryFormatter . class 包装了一个引用计数的非托管句柄,该句柄使用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).为了使引用计数与活动的 .NET 实例保持同步,我在[OnSerialized]处理程序中将其增加 1,假设 object 将被反序列化一次,这在上述场景中是违反的(反序列化后序列化位被丢弃)。

Implementing ISerializable instead of using [OnSerialized] attribute works: GetObjectData gets called for each distinct object even if they are equal by Equals + GetHashCode .实现ISerializable而不是使用[OnSerialized]属性有效: GetObjectData会为每个不同的 object 调用,即使它们等于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)现在从包装器派生的所有类型都必须具有带有签名的反序列化构造函数.ctor(SerializationInfo info, StreamingContext context)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM