现有一个对象(objectA)需要用BinaryFormatter序列化成二进制文件:
FileStream fileStream = new FileStream(path, FileMode.Create); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(fileStream, objectA);
对象objectA的定义如下:
[Serializable()] public class ObjectA { public string Name { set; get; } public event EventHandler<EventArgs> Created; }
注意:对象ObjectA有一个事件:Created.
如果在不能被序列化的对象(譬如WinForm里面)订阅了ObjectA的Created事件,那么在序列化时,就会出错:
对此,我并没有找到很好的解释,就连微软的官方文档里面也只字未提(还是我没有看懂)。
http://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.formatters.binary.binaryformatter(v=vs.100).aspx
给出完整代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.Serialization.Formatters.Binary; using System.IO; namespace BinarySerializer { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { SaveFileDialog dialog = new SaveFileDialog(); if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { try { ObjectA objectA = new ObjectA { Name = "A" }; if (checkBox1.Checked) objectA.Created += new EventHandler<EventArgs>(objectA_Created);//对象在被序列化时,如果对象的事件被其他对象订阅了,则会出现序列化失败错误,将这句注销就序列化成功。 string path = dialog.FileName; FileStream fileStream = new FileStream(path, FileMode.Create); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(fileStream, objectA); MessageBox.Show("保存成功"); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } void objectA_Created(object sender, EventArgs e) { throw new NotImplementedException(); } } [Serializable()] public class ObjectA { public string Name { set; get; } public event EventHandler<EventArgs> Created; } }
Demo: 带事件的对象序列化失败Demo
解决方案:
在事件上加“ [field: NonSerialized]”标签,就不会再序列化事件了。
http://www.baryudin.com/blog/events-and-binaryformatter-serialization-net.html
http://stackoverflow.com/questions/2308620/why-is-binaryformatter-trying-to-serialize-an-event-on-a-serializable-class