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

发布于 2024-08-22 13:44:15 字数 821 浏览 4 评论 0原文

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

}

I have a simple class that is marked as Serializable, and it happens to have an event. I tried to mark the event member as NonSerialized, however the compiler complains. Yet when I go to serialize the class instance, the BinaryFormatter throws an exception that the event is non serializable. Does that mean you can't serialize classes that have events? If so, then the compiler should say so up front.

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);
}

Fails to work on the following class:

[Serializable()]
class Simple
{
    private int myInt;
    private string myString;
    public event SomeOtherEventDefinedElsewhere TheEvent;

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小兔几 2024-08-29 13:44:15

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


前缀 NonSerializedAttribute 带有字段

[field:NonSerialized]
public event MyEventHandler MyEvent;

"In the case of events, you must also
add the field attribute qualifier when
applying the NonSerialized attribute
so that the attribute is applied to
the underlying delegate rather than to
the event itself"
Advanced Serialization - MSDN


Prefix the NonSerializedAttribute with field

[field:NonSerialized]
public event MyEventHandler MyEvent;
一抹微笑 2024-08-29 13:44:15

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

It is important to remember that the attribute is [Field:NonSerialized] is applied to the delegates, not the events, case sensitive by the way, then implement a ISerializable object, and using reflection, iterate through the class that you are serializing, looking for the event handler, and unsubscribe the events first prior to serializing. Then when doing the deserializing, you can then wire up the events if necessary automatically on deserializing...

难得心□动 2024-08-29 13:44:15

我知道这是一篇迟到的文章,但这是这个问题的实际答案。为您的事件创建手动添加/删除“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)或在线搜索;不幸的是我没有时间,因为我必须跑步,但你明白了。

希望这有帮助!

I know this is a late post but here's an actual answer to this question. Create manual add/remove "getters/setters" for your event (the compiler does this for you behind the scenes but in this case you must do so explicitly) then mark your event as NonSerialized. I don't have time to break out the code for you but a quick search reveals someone who ran into the same issue :

http://sanity-free.org/113/csharp_binary_serialization_oddities.html

Do not use this line however : [MethodImpl(MethodImplOptions.Synchronized)]

This leads to thread-safety issues which was fixed in C# 4; see :

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

You'll either need to roll your own lockless alternative (using CAS) or search online for one; unfortunately I don't have the time as I have to run but you get the idea.

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文