【问题标题】:Custom equality comparer for `BinaryFormatter``BinaryFormatter` 的自定义相等比较器
【发布时间】:2021-11-24 01:25:17
【问题描述】:

TL;DR;

我的自定义[Serializable] 类覆盖了GetHashCodeEquals,因此多个不同的对象可以“相等”,并且看起来BinaryFormatter 只调用了一次OnSerialized,但两个时调用了两次OnDeserialized图中存在相等但不同的 (ReferenceEquals == false) 对象。

如果我想保留我的 GetHashCodeEquals 实现,我可以做些什么来确保每次调用 [OnSerialized] 方法 [OnDeserialized] 方法只被调用一次?

理想情况下,我想指示BinaryFormatter 将我的IEqualityComparer 自定义实现用于我的自定义类,这样它就不会尝试“合并”不同但相等的实例。

背景

该类包装了一个引用计数的非托管句柄,该句柄使用BinaryFormatter 跨应用程序域传递。为了使引用计数与活动的 .NET 实例保持同步,我在 [OnSerialized] 处理程序中将其增加 1,假设对象将被反序列化一次,这在上面的场景中是违反的(反序列化后序列化位被丢弃)。

【问题讨论】:

  • 我认为[OnDeseriaized] 只被调用一次是没有意义的。您需要反序列化的对象才能使用GetHashCodeEquals. 这似乎是XY Problem 无论如何。特别是:您为什么为此使用BinaryFormatter?您能否展示一些代码以提供更好的图片?
  • 您看过BinaryFormatter 文档docs.microsoft.com/en-us/dotnet/api/…,尤其是这部分:“警告 BinaryFormatter 不安全,无法确保安全。”
  • @Flydog57 BinaryFormatter 的安全问题与我的情况无关,因为我的库只反序列化它之前序列化的内容。
  • @Llama 我通过在背景部分提到我的用例来预料到 XY 的事情:我需要保留包装非托管资源的类实例,并在应用程序中自定义实现 GetHashCodeEquals域。特别是对于 Unity 编辑器。
  • 嗯,你能提供一些代码(minimal reproducible example)吗?

标签: c# binaryformatter binary-serialization


【解决方案1】:

实现ISerializable 而不是使用[OnSerialized] 属性有效:GetObjectData 会为每个不同的对象调用,即使它们等于Equals + GetHashCode

缺点是:

  1. 可能比较慢
  2. 现在从包装器派生的所有类型都必须有一个带有签名.ctor(SerializationInfo info, StreamingContext context) 的反序列化构造函数

【讨论】:

    猜你喜欢
    • 2012-11-11
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    • 2017-11-02
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多