在问题How to exclude nonserializable observers from a [Serializable] INotifyPropertyChanged implementor?的答案中,我找到了一个很好的策略,可以排除具有不可序列化目标的事件处理程序。所以我在我的代码中使用它。
但是在序列化时,代码执行似乎突然变成BinaryFormatter
代码中的无限循环。这没有任何例外。如果我在Visual Studio中尝试逐步执行,只有一个简单的语句,并且在到达虚构时没有循环。所有序列化对象都是一种基本类型,其中定义了事件和序列化。此外,首先BinaryFormatter
在到达循环之前很好地序列化层次结构中的一些上层对象。到达后,显示的Window
内容将变为全黑。如果我在调试时打开并行线程窗口,则在进入循环后没有线程。
有谁知道这有什么原因?
基类的代码和从它派生的子库类如下所示:
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<T>