我的主窗体上有一个按钮,它调用一个将一些对象序列化到磁盘的方法。我正在尝试将这些对象添加到 ArrayList,然后使用 BinaryFormatter 和 FileStream 对它们进行序列化。
public void SerializeGAToDisk(string GenAlgName)
{
// Let's make a list that includes all the objects we
// need to store a GA instance
ArrayList GAContents = new ArrayList();
// Structure and info for a GA
GAContents.Add(GenAlgInstances[GenAlgName]);
// There may be several running GA's
GAContents.Add(RunningGAs[GenAlgName]);
using (FileStream fStream = new FileStream(GenAlgName + ".ga",
FileMode.Create, FileAccess.Write, FileShare.None))
{
BinaryFormatter binFormat = new BinaryFormatter();
binFormat.Serialize(fStream, GAContents);
}
}
运行上述代码时,出现以下异常:
System.Runtime.Serialization.SerializationException 未处理程序集“GeneticAlgApp,版本=1.0.0.0,文化=中性,PublicKeyToken=null”中的消息=类型“WindowsFormsApplication1.Form1”未标记为可序列化。
所以这意味着在我试图保存的对象中的某个地方必须有对主表单的引用。我能看到的唯一可能的引用是 3 个委托,它们都指向主表单代码中的方法。代表也会被序列化吗?我似乎无法将[NonSerialized]
属性应用于它们。
还有什么我可能会丢失的吗?更好的是,是否有一种快速的方法可以找到导致问题的参考?
更新:
好吧,我通过将委托保存到临时变量中然后在序列化之前将它们设置为 null 来使我的代码工作。然后我将它们设置回原来的值。似乎应该有更好的方法来做到这一点。请问有什么意见吗?
回答:
除了在序列化之前将它们设置为 null 之外,我想不出一种方法来阻止我的委托被序列化,但是我认为最好的解决方案是更改我的代码以改用事件。正如 Mark Gravell 在他的回答中所说,事件可以通过使用[field:Nonserialized]
属性标记从序列化中省略。问题解决了。实际上没有人建议这个,但我想马克的回答是最接近的。