【问题标题】:Change auto implemented properties to normal and deserialization with BinaryFormatter使用 BinaryFormatter 将自动实现的属性更改为正常和反序列化
【发布时间】:2012-12-05 14:06:26
【问题描述】:

我有一个对象,其属性实现如下

public String Bla {get;set;} 

将实现更改为类似

private String _bla;

public String Bla
{
    get { return _bla; }
    set { _bla = value; } 
} 

反序列化时,此属性为空。

我有很多来自旧实现的序列化数据,并希望用新实现加载它们

有什么方法可以改变实现以兼容旧的二进制文件?

编辑:

有些人可能会遇到同样的问题,所以这是我的 hackish 解决方案:

自动生成的字段的命名约定是无效的 c# 代码:

[CompilerGenerated]
private string <MyField>k__BackingField;

[CompilerGenerated]
public void set_MyField(string value)
{
    this.<MyField>k__BackingField = value;
}

[CompilerGenerated]
public string get_MyField()
{
    return this.<MyField>k__BackingField;
}

对我来说快速而肮脏的解决方法是在源代码中创建一个名为 xMyFieldxK__BackingField 的私有支持字段,

并通过在反序列化之前将所有出现的&lt;MyField&gt; 替换为xMyFieldx 来修补序列化的二进制数据

【问题讨论】:

  • “与旧的二进制文件兼容”是什么意思?
  • @GregorPrimar:我有很多来自旧实现的序列化数据,并希望用新实现加载它们
  • 我非常怀疑您是否可以使用二进制反序列化来做到这一点。您应该使用 XmlSerializer,然后您也可以反序列化旧版本。
  • 其实这两种实现没有区别。如果您使用的是第一个实现,编译器会创建与第二个实现非常相似的代码。因此,您必须有理由更改代码 - 例如控制对属性的访问。你能告诉我们你的代码的更多细节吗? (更多信息可以在这里找到:codeproject.com/Articles/266593/How-does-it-work-in-Csharp

标签: c# .net serialization automatic-properties


【解决方案1】:

尝试实现ISerializable

    [SecurityCritical]
    public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        if (info == null)
            throw new ArgumentNullException("info");

        info.AddValue("name of compiler generated field", _bla);
    }

【讨论】:

  • 这是一个解决方案,但如果使用大型代码库,那肯定很糟糕。不过我有个主意;p
  • 代码库很大很可怕,但正确的方法。我用我的发现更新了我的问题
【解决方案2】:

BinaryFormatter 序列化字段,而不是属性。

您可以通过查看 ILSpy 中自动生成的字段名称或类似名称并以这种方式命名您的名称来使其工作。

否则,如 Henrik 所述,您必须编写自己的反序列化,请参阅 this question 了解更多信息

您可能可以通过实现ISerializable 和特殊情况的此字段来检查反序列化信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    • 2010-12-10
    相关资源
    最近更新 更多