【问题标题】:BinaryFormatter deserialize delegate field after change in classBinaryFormatter 在类更改后反序列化委托字段
【发布时间】:2019-01-04 17:14:14
【问题描述】:

在 C# 中使用 BinaryFormatter,我试图从包含委托属性的类中反序列化对象。

在委托引用的类上添加成员后,反序列化中断。 请参见下面的示例。

即使我完全忽略有问题的委托属性,我也需要反序列化才能工作。 例如,如果委托属性始终反序列化为 null,则问题将得到解决。 我无法通过将属性标记为 [NonSerialized] 或将其更改为字段来解决它。

下面将描述我试图反序列化的序列化对象。

public class mySerializedClass
{
    public string thisIsOK1 {get; set;}
    public string thisIsOK2 {get; set;}
    public Func<myModelClass,bool> thisIsTheIssue {get; set;}
}

[Serializable]
public class myModelClass
{
    // The issue happened after adding a new method to this class

    public static bool testMethod(mySerializedClass obj)
    {
        // do stuff
        return true
    }
}

作为序列化实例的示例:

new mySerializedClass()
{
    thisIsOK1 = "a";
    thisIsOK2 = "b";
    thisIsTheIssue = (o) => myModelClass.testMethod(o);    
}

一个有效的解决方案是始终将“thisIsTheIssue”属性序列化/反序列化为 null。

作为附加信息,异常消息是:

无法获取成员“get_theNameOfMyDelegate b__19_0”。

异常的 StackTrace 是:

在 System.Reflection.MemberInfoSerializationHolder.GetRealObject(StreamingContext 上下文)在 System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder 持有人)在 System.Runtime.Serialization.ObjectManager.DoFixups()
在 System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler 处理程序,__BinaryParser serParser,布尔 fCheck,布尔 isCrossAppDomain, IMethodCallMessage methodCallMessage) 在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(流 serializationStream, HeaderHandler 处理程序, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) 在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(流 serializationStream) 在...我的代码中我反序列化的地方...

【问题讨论】:

  • 请描述“反序列化中断”。异常或错误的细节很重要。
  • @ScottHannen,添加了有关异常的信息。谢谢
  • 您提到向第二个类添加方法时发生异常,并且您尝试添加属性以防止序列化。你能举一个例子来说明这些事情吗?然后也许我可以创建一个类的实例并尝试序列化它。
  • @ScottHannen,添加了一个示例实例,希望对您有所帮助,真实案例是遗留代码,非常复杂,我希望我能合理地描述问题
  • 异常消息与 sn-p 不匹配。但是序列化委托通常是一个非常糟糕的主意,尤其是当您使用 lambda 表达式时。 C# 编译器将它们翻译成一个名字很奇怪的方法,这个名字是稳定的并且即使是很小的代码修改后它仍然是“b__19_0”的可能性很低。当您承诺二进制序列化时,您也承诺在客户的数据需要生存的情况下不再进行任何更改。

标签: c# .net deserialization binaryformatter binary-serialization


【解决方案1】:

我会考虑版本控制类,或者将您的传输与您的工作类分开。

所以你可能有一个 mySerializedClass 但随后有一个 myWorkingClass

包含委托。在序列化和反序列化时,您将在 mySerializedClass 中加载和保存 myWorkingClass。然后,您可以在应用程序获得新功能时快速执行诸如拥有不同版本的 mySerializedClass 之类的事情。

【讨论】:

  • 您描述的方法可以防止这个问题,并且可能是长期的前进方向。鉴于有我需要使用的序列化数据,我仍然需要开发一个解决方案,即使忽略有问题的属性,我也可以反序列化现有数据。老实说,我们可能更愿意完全避免使用 BinaryFormatter。
猜你喜欢
  • 1970-01-01
  • 2018-08-20
  • 1970-01-01
  • 2010-12-10
  • 2012-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
相关资源
最近更新 更多