メイン フォームに、いくつかのオブジェクトをディスクにシリアル化するメソッドを呼び出すボタンがあります。これらのオブジェクトを 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 が処理されませんでした Message=Type 'WindowsFormsApplication1.Form1' in Assembly 'GeneticAlgApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' はシリアル化可能としてマークされていません。
つまり、保存しようとしているオブジェクトのどこかに、メイン フォームへの参照が必要です。私が見ることができる唯一の可能な参照は、すべてメイン フォーム コードのメソッドを指す 3 つのデリゲートです。デリゲートもシリアル化されますか? [NonSerialized]
それらに属性を適用できないようです。
私が見逃している可能性のあるものは他にありますか?さらに良いことに、問題の原因となっている参照をすばやく見つける方法はありますか?
アップデート:
デリゲートを一時変数に保存し、シリアル化の前にそれらを null に設定することで、コードが機能するようになりました。その後、元の値に戻します。これを行うためのより良い方法があるはずです。コメントをお願いします。
答え:
シリアル化する前にデリゲートを null に設定する以外に、デリゲートのシリアル化を停止する方法がわかりませんでしたが、代わりにイベントを使用するようにコードを変更するのが最善の解決策だと思います。Mark Gravell が彼の回答で述べたように、イベントは[field:Nonserialized]
属性でマークすることでシリアル化から除外できます。問題が解決しました。誰も実際にこれを提案しませんでしたが、マークの答えが最も近いと思います。