13

我有一个标记为可序列化的简单类,它恰好有一个事件。我试图将事件成员标记为 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;

}

4

3 回答 3

25

“在事件的情况下,您还必须在应用 NonSerialized 属性时添加字段属性限定符,以便将属性应用于底层委托而不是事件本身” 高级序列化 - MSDN


前缀NonSerializedAttributewith 字段

[field:NonSerialized]
public event MyEventHandler MyEvent;
于 2010-02-22T03:30:59.637 回答
0

重要的是要记住该属性[Field:NonSerialized]应用于委托,而不是事件,顺便说一下区分大小写,然后实现一个 ISerializable 对象,并使用反射,遍历您正在序列化的类,寻找事件处理程序,并在序列化之前先取消订阅事件。然后在进行反序列化时,如果需要,您可以在反序列化时自动连接事件......

于 2010-02-22T03:51:17.370 回答
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),要么在网上搜索一个;不幸的是,我没有时间,因为我必须跑步,但你明白了。

希望这可以帮助!

于 2015-08-06T21:13:54.200 回答