反序列化后 IReactiveDerivedList 损坏

IReactiveDerivedList broken after deserialization

当我使用 ReactiveListIReactiveDerivedList 创建 ViewModel,然后使用 Json.net 对其进行序列化和反序列化时,派生列表似乎已损坏。我做错了什么?

视图模型:

[DataContract]
public class TestViewModel : ReactiveObject
{
    [DataMember]
    public ReactiveList<int> List { get; } = new ReactiveList<int>();

    public IReactiveDerivedList<int> DerivedList { get; }

    public TestViewModel()
    {
        //DerivedList contains all elements of List that are greater than 0.
        DerivedList = List.CreateDerivedCollection(v => v, v => v > 0);
    }
}

序列化测试:

private void Example()
{
    TestViewModel vm = new TestViewModel();
    vm.List.Add(0);
    vm.List.Add(1);

    //vm.DerivedList now has 1 item

    string json = JsonConvert.SerializeObject(vm);
    TestViewModel clone = JsonConvert.DeserializeObject<TestViewModel>(json);

    //vm.DerivedList now has 1 item
    //clone.DerivedList now has 1 item

    vm.List.Add(1);
    clone.List.Add(1);

    //vm.DerivedList now has 2 items
    //clone.DerivedList now has 1 item
}

我认为这里的问题是当ViewModel被反序列化时,作为派生列表源的ReactiveList也被反序列化,这就是问题所在。

当你的 TestViewModel 被反序列化时,事件的顺序是这样的:

最后一步是出现问题的地方。派生集合订阅了 old observables,而不是 ReactiveList 现在正在使用的那些。修复它的一种方法是为派生列表 属性 提供一个私有 setter,实现一个 deserialization callback,并在该回调中创建派生列表。

[DataContract]
public class TestViewModel : ReactiveObject
{
    [DataMember]
    public ReactiveList<int> List { get; } = new ReactiveList<int>();

    public IReactiveDerivedList<int> DerivedList { get; private set; }

    public TestViewModel()
    {
        SetupRx();
    }

    [OnDeserialized]
    internal void OnDeserialized(StreamingContext context)
    {
        SetupRx();
    }

    private void SetupRx()
    {
        DerivedList?.Dispose();
        DerivedList = List.CreateDerivedCollection(v => v, v => v > 0);
    }
}