为什么BinaryFormatter尝试序列化Serializable类上的事件?

时间:2010-02-22 03:26:23

标签: c# .net serialization binaryformatter

我有一个标记为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;

}

3 个答案:

答案 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中修复的线程安全问题;见:

http://blogs.msdn.com/b/cburrows/archive/2010/03/05/events-get-a-little-overhaul-in-c-4-part-i-locks.aspx

您需要使用自己的无锁替代方案(使用CAS)或在线搜索一个;不幸的是,我没有时间,因为我必须跑,但你明白了。

希望这有帮助!