现有一个对象(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 EventHandlerCreated; }
注意:对象ObjectA有一个事件:Created.
如果在不能被序列化的对象(譬如WinForm里面)订阅了ObjectA的Created事件,那么在序列化时,就会出错:
对此,我并没有找到很好的解释,就连微软的官方文档里面也只字未提(还是我没有看懂)。
给出完整代码:
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(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 Created;}}
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