3

メイン フォームに、いくつかのオブジェクトをディスクにシリアル化するメソッドを呼び出すボタンがあります。これらのオブジェクトを 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]属性でマークすることでシリアル化から除外できます。問題が解決しました。誰も実際にこれを提案しませんでしたが、マークの答えが最も近いと思います。

4

3 に答える 3

2

これはほとんどの場合、フォームからイベントを購読したことを意味します。はい、デリゲート フィールドは、使用時にデフォルトでシリアル化されます。これは、イベントBinaryFormatterがシリアル化されることを意味します。イベントを確認してください。通常は、バッキング デリゲートをマークする必要があります。フィールドのようなイベントの場合は、 を使用します。例えば:[NonSerialized][field:NonSerialized]

[field:NonSerialized]
public event EventHandler Foo;

また:

[NonSerialized]
private EventHandler foo;

public event EventHandler {
    add { foo += value; }
    remove { foo -= value; }
}
于 2012-09-10T08:52:27.187 に答える
0

すべての参照を検索するには、Visual Studioでそのクラス(ここではメインフォームだと思います)を右クリックし、[すべての参照を検索](Ctrl + K、R)を選択
します。また、[Serializable]属性が必要なものをシリアル化する場合もあります。 。
そして、デリゲートをシリアル化できるとは思いません。

于 2012-09-10T08:45:47.920 に答える
0

オブジェクトがシリアル化をサポートしていない可能性があります。カスタム オブジェクトの場合は、[Serializable] 属性でマークします。また、この記事を読んで、カスタムのシリアル化プロセスを実装する方法を知ることができます。

于 2012-09-10T08:42:11.153 に答える