我有一个标记为Serializable的简单类,它碰巧有一个事件。我试图将事件成员标记为NonSerialized,但编译器抱怨。然而,当我去序列化类实例时,BinaryFormatter会抛出一个异常,即事件是不可序列化的。这是否意味着您无法序列化具有事件的类?如果是这样,那么编译器应该事先说出来。
Stream file = File.Open("f", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
object obj = null;
try
{
obj = bf.Deserialize(file);
}
catch (System.Runtime.Serialization.SerializationException e)
{
MessageBox.Show("De-Serialization failed : {0}", e.Message);
}
file.Close();
System.Collections.ArrayList nodeList = obj as System.Collections.ArrayList;
foreach (TreeNode node in nodeList)
{
treeView.Nodes.Add(node);
}
无法处理以下类:
[Serializable()]
class Simple
{
private int myInt;
private string myString;
public event SomeOtherEventDefinedElsewhere TheEvent;
}
答案 0 :(得分:20)
“就事件而言,你也必须 何时添加字段属性限定符 应用NonSerialized属性 以便应用该属性 基础代表而不是 事件本身“ Advanced Serialization - MSDN
使用字段
添加NonSerializedAttribute
前缀
[field:NonSerialized]
public event MyEventHandler MyEvent;
答案 1 :(得分:0)
重要的是要记住,属性[Field:NonSerialized]
应用于委托,而不是事件,顺便提一下,然后实现一个ISerializable对象,并使用反射,遍历你所在的类序列化,查找事件处理程序,并在序列化之前首先取消订阅事件。然后在进行反序列化时,您可以在反序列化时自动连接事件......
答案 2 :(得分:0)
我知道这是一个迟到的帖子,但这里是这个问题的实际答案。为您的事件创建手动添加/删除“getters / setters”(编译器在幕后为您执行此操作,但在这种情况下您必须明确地执行此操作),然后将您的事件标记为NonSerialized。我没有时间为您分解代码,但快速搜索显示有人遇到了同样的问题:
http://sanity-free.org/113/csharp_binary_serialization_oddities.html
不要使用此行:[MethodImpl(MethodImplOptions.Synchronized)]
这导致了C#4中修复的线程安全问题;见:
您需要使用自己的无锁替代方案(使用CAS)或在线搜索一个;不幸的是,我没有时间,因为我必须跑,但你明白了。
希望这有帮助!