Why is BinaryFormatter trying to serialize an Event on a Serializable class?

最后都变了- 提交于 2019-11-27 17:54:41

问题


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;

}


回答1:


"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;



回答2:


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...




回答3:


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!



来源:https://stackoverflow.com/questions/2308620/why-is-binaryformatter-trying-to-serialize-an-event-on-a-serializable-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!