【问题标题】:Don't raise OnPropertyChanged when deserializing反序列化时不要引发 OnPropertyChanged
【发布时间】:2013-08-27 13:54:07
【问题描述】:

假设我有这门课:

[XmlType]
public class TestModel : BindableBase
{
    private int _id;

    [XmlElement(Order = 7)]
    public int Id
    {
        get
        {
            return _id;
        }
        set
        {
            SetProperty(ref _id, value);
        }
    }
}

我正在进行大量的序列化和反序列化(使用 newtonsoft 从/到 Json 以及使用 protobuf 从/到字节数组),并且我希望在反序列化期间设置属性时避免调用 SetProperty 方法。

基本上我想有一些类似的东西:

[XmlElement(Order = 7)]
public int Id
{
    get
    {
        return _id;
    }
    set
    {
        if(!serializing) 
            SetProperty(ref _id, value);
        else
            _id = value;
    }
}

我想这样做的原因是首先我不需要在反序列化期间引发事件OnPropertyChanged,其次因为它在性能方面的成本很高。

我尝试使用OnDeserializingOnDeserialized 设置标志,但OnDeserialized 让我知道反序列化何时结束,用OnDeserializing 修饰的方法不是在反序列化之前而是在操作期间调用。

此代码位于可移植类库程序集中,因此我无法使用 SerializationContext

欢迎提供任何线索/提示!

【问题讨论】:

  • 在反序列化之前调用标有 OnDeserializing 的方法是什么意思?您的意思是在实例化对象之后但在设置属性之前调用它们?

标签: c# serialization windows-runtime portable-class-library


【解决方案1】:

我想到的最简单的事情是在整个代码中使用参数化构造函数,它将“序列化”标志设置为 false,并在无参数构造函数中将“序列化”标志设置为 true。除了第一个,您还可以使用 Factory,它也将使用无参数构造函数,但会在创建后适当地设置标志。

【讨论】:

  • 我不能这样做,因为已反序列化的实例将在运行时更改其属性。这将是同一个实例;首先它将从字节数组/json 中反序列化,然后将在程序集之外进行操作。
  • 是的,但是您已经解决了这个问题 - OnDeserialized 让您知道反序列化何时结束,不是吗?
  • 然而这引入了一个奇怪的概念耦合——由默认构造函数创建的对象是“特殊的”并且它不是很可读。而且您不能将这些构造函数设为私有,因为您可能无法反序列化它们。也许有更好的解决方案。
  • 也许用“[Obsolete]”属性标记这些构造函数是个好主意,以帮助防止在代码中显式使用它们。
  • 是的,我同意你的观点,但我暂时想不出其他方法。
猜你喜欢
  • 1970-01-01
  • 2011-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-05
  • 1970-01-01
相关资源
最近更新 更多