Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 序列化时不能排除不可序列化的事件处理程序_C#_Wpf_Events_Serialization_Mvvm - Fatal编程技术网

C# 序列化时不能排除不可序列化的事件处理程序

C# 序列化时不能排除不可序列化的事件处理程序,c#,wpf,events,serialization,mvvm,C#,Wpf,Events,Serialization,Mvvm,在问题的答案中,我找到了一个很好的策略,可以排除具有不可变目标的事件处理程序。所以我在代码中使用了它 但是,在序列化过程中,代码执行似乎突然在BinaryFormatter代码中进入了一个无休止的循环。这是毫无例外的。如果我尝试在VisualStudio中一步一步地执行,那么当到达虚构的语句时,只有一个简单的语句,没有循环。所有序列化对象都属于一种基本类型,在该类型中定义了事件和序列化。此外,在到达循环之前,BinaryFormatter首先序列化层次结构中的一些上层对象。当到达时,显示的窗口内

在问题的答案中,我找到了一个很好的策略,可以排除具有不可变目标的事件处理程序。所以我在代码中使用了它

但是,在序列化过程中,代码执行似乎突然在BinaryFormatter代码中进入了一个无休止的循环。这是毫无例外的。如果我尝试在VisualStudio中一步一步地执行,那么当到达虚构的语句时,只有一个简单的语句,没有循环。所有序列化对象都属于一种基本类型,在该类型中定义了事件和序列化。此外,在到达循环之前,BinaryFormatter首先序列化层次结构中的一些上层对象。当到达时,显示的窗口内容将完全变为黑色。如果在调试时打开“并行线程”窗口,则进入循环后没有线程

有人知道这是什么原因吗

基类及其派生的子类的代码如下所示:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Runtime.Serialization;

[Serializable]
public class A // : INotifyPropertyChanged
{
    private List<Delegate> _serializablePropertyChangedDelegates;
    private List<Delegate> _serializableSubmodelPropertyChangedDelegates;

    public A()
    {
        _serializablePropertyChangedDelegates=new List<Delegate>();
        _serializableSubmodelPropertyChangedDelegates=new List<Delegate>();
    }

    [field : NonSerialized]
    public event PropertyChangedEventHandler PropertyChanged;

    [field : NonSerialized]
    public event PropertyChangedEventHandler SubmodelPropertyChanged;

    [OnSerializing]
    protected void OnSerializing(StreamingContext context)
    {
        VirtualOnSerializing(context);
    }

    protected virtual void VirtualOnSerializing(StreamingContext context)
    {
        _serializablePropertyChangedDelegates=new List<Delegate>();
        if(PropertyChanged!=null)
        {
            foreach(Delegate invocation in PropertyChanged.GetInvocationList())
            {
                if((invocation.Target==null)||(invocation.Target.GetType().IsSerializable))
                {
                    _serializablePropertyChangedDelegates.Add(invocation);
                }
            }
        }
        _serializableSubmodelPropertyChangedDelegates=new List<Delegate>();
        if(SubmodelPropertyChanged!=null)
        {
            foreach(Delegate invocation in SubmodelPropertyChanged.GetInvocationList())
            {
                if((invocation.Target==null)||(invocation.Target.GetType().IsSerializable))
                {
                    _serializableSubmodelPropertyChangedDelegates.Add(invocation);
                }
            }
        }
    }

    [OnDeserialized]
    protected void OnDeserialized(StreamingContext context)
    {
        foreach(Delegate invocation in _serializablePropertyChangedDelegates)
        {
            PropertyChanged += (PropertyChangedEventHandler)(invocation);
        }
        foreach(Delegate invocation in _serializableSubmodelPropertyChangedDelegates)
        {
            SubmodelPropertyChanged += (PropertyChangedEventHandler)(invocation);
        }
    }

    // [...]
}

[Serializable]
public class B<T> : A //, INotifyCollectionChanged, IList<T>
    where T : A
{
    private List<Delegate> _serializableCollectionChangedDelegates;

    private B()
    {
        _serializableCollectionChangedDelegates=new List<Delegate>();
    }

    [field : NonSerialized]
    public event NotifyCollectionChangedEventHandler CollectionChanged;

    protected override void VirtualOnSerializing(StreamingContext context)
    {
        base.VirtualOnSerializing(context);
        _serializableCollectionChangedDelegates=new List<Delegate>();
        if(CollectionChanged!=null)
        {
            foreach(Delegate invocation in CollectionChanged.GetInvocationList())
            {
                if((invocation.Target==null)||(invocation.Target.GetType().IsSerializable))
                {
                    _serializableCollectionChangedDelegates.Add(invocation);
                }
            }
        }
    }

    [OnDeserialized]
    protected void OnDeserialized(StreamingContext context)
    {
        base.OnDeserialized(context);
        foreach(Delegate invocation in _serializableCollectionChangedDelegates)
        {
            CollectionChanged += (NotifyCollectionChangedEventHandler)(invocation);
        }
    }

    // [...]
}

在子类中,没有声明其他事件。如果我不声明序列化方法,那么它工作得很好。所有其他类都是从A或B派生的

@HansPassant:对不起。您还需要其他东西吗?@HansPassant:事件处理程序只是从A派生的模型类或从ReactiveObject派生的不可序列化视图模型类的方法。模型类的序列化字段仅为标准值类型或从A派生的类型。现在,我更改了事件处理程序序列化条件,使其仅在invocation.Target.GetType基于A时为true。因此,序列化在逐步调试时起作用。但现在反序列化不起作用。上面的代码中添加了相应的方法。@HansPassant反序列化似乎可以工作。这些模型有效。但是视图模型的行为不同,这取决于是创建了新的主模型对象还是反序列化了旧的主模型对象。不处理模型中的更改,或在ReactiveUI中引发错误。但是模型被传递给视图模型,视图模型添加了必要的事件处理程序来响应模型。因此,所有这些都必须以同样的方式进行。这怎么可能?