none
FormのSerializeについて RRS feed

  • 質問

  • シリアライズについて教えて下さい。

     

    以下2つを作りました。

    • クラスData
    • formからの継承クラスForm2

    コードはこんな感じです。

    • クラスData
    Code Snippet

        [Serializable]
        class Data
        {
            public short ShortData
            {
                get
                {
                    return shortData;
                }
                set
                {
                    shortData = value;
                }
            }

            public double DoubleData
            {
                get
                {
                    return doubleData;
                }
                set
                {
                    doubleData = value;
                }
            }

            private short shortData = 0;

            private double doubleData = 0;
        }

     

     

    • formからの継承クラスForm2

    Code Snippet

        [Serializable]
        public partial class Form2 : Form
        {
            private short sdata = 0;

            public Form2()
            {
                InitializeComponent();
            }
        }

     

     

    この時、以下のコードでdataをシリアライズした場合エラーはでませんが、form2をシリアライズすると例外が出ます。

    ”シリアル化可能として設定されていません”

    何故でしょうか?。

     

    Code Snippet

            private Data data = new Data();

            private Form2 form2 = new Form2();

            public Form1()
            {
                InitializeComponent();
            }

            private void button1_Click(object sender, EventArgs e)
            {
                String savePath = Application.LocalUserAppDataPath + Properties.Resources.FileName;

                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                using (System.IO.FileStream fs = new System.IO.FileStream(savePath, System.IO.FileMode.Create))
                {
                    bf.Serialize(fs, data);
    //              bf.Serialize(fs, form2);
                }
            }

     

     

     

     

     

     

    2008年12月7日 0:18

回答

  • 例外メッセージはもうちょっと親切に記述されているはずです。「何が」シリアル化可能として設定されていないかをまず確認してください。

    そして SerializableAttribute の解説には以下の記述があります。

    シリアル化されたオブジェクトのグラフで、いずれかの型に SerializableAttribute 属性が適用されていない場合、共通言語ランタイムは SerializationException をスローします。

    グラフってのは要するに継承ツリーのことです。継承元のどこかに一つでも Serializable 属性がついていなければシリアライズできない、と書かれています。

    // まあ、Handle なんてもんが存在している Control 系をシリアライズできないのは当然ですね。

     

    ISerializable インターフェイスを実装することでシリアライズの動作を完全にオーバーライドすることは可能ですが、そんなことするぐらいなら必要なデータだけを集めたクラスを用意してそちらをシリアライズする方がいいでしょう。

    2008年12月7日 1:42

すべての返信

  • 例外メッセージはもうちょっと親切に記述されているはずです。「何が」シリアル化可能として設定されていないかをまず確認してください。

    そして SerializableAttribute の解説には以下の記述があります。

    シリアル化されたオブジェクトのグラフで、いずれかの型に SerializableAttribute 属性が適用されていない場合、共通言語ランタイムは SerializationException をスローします。

    グラフってのは要するに継承ツリーのことです。継承元のどこかに一つでも Serializable 属性がついていなければシリアライズできない、と書かれています。

    // まあ、Handle なんてもんが存在している Control 系をシリアライズできないのは当然ですね。

     

    ISerializable インターフェイスを実装することでシリアライズの動作を完全にオーバーライドすることは可能ですが、そんなことするぐらいなら必要なデータだけを集めたクラスを用意してそちらをシリアライズする方がいいでしょう。

    2008年12月7日 1:42
  • Hongliangさん。

     

    ご返答ありがとうございます。

    フォーラムに投稿する前にSerializableAttributeの説明を読みましたが、

    ”グラフ”という表現が何を指しているか理解できず、混乱していましたが、ご説明で理解することができました。

     

    有難うございました。

    2008年12月7日 7:56
  •  Hongliang さんからの引用
    グラフってのは要するに継承ツリーのことです。継承元のどこかに一つでも Serializable 属性がついていなければシリアライズできない、と書かれています。

     

    今回の件は派生元が Serializable ではなかったのが直接の原因というのはそうだと思いますが,この書き方も誤解を生むような.シリアライズの文脈でグラフというと,一般にはオブジェクトの参照グラフを指すんじゃないかと.

    (循環を含んでよい参照グラフで結びついたオブジェクト群を,まとめてシリアライズしたいというのがこの辺の設計の動機になってますよね)

    2008年12月7日 9:01
  •  NyaRuRu さんからの引用

     Hongliang さんからの引用
    グラフってのは要するに継承ツリーのことです。継承元のどこかに一つでも Serializable 属性がついていなければシリアライズできない、と書かれています。

     

    今回の件は派生元が Serializable ではなかったのが直接の原因というのはそうだと思いますが,この書き方も誤解を生むような.シリアライズの文脈でグラフというと,一般にはオブジェクトの参照グラフを指すんじゃないかと.

    (循環を含んでよい参照グラフで結びついたオブジェクト群を,まとめてシリアライズしたいというのがこの辺の設計の動機になってますよね)


    はい、全くその通りですね。訂正します。
    とは言え語彙不足で今回の件をうまく表現できないですが。
    // 説明できないってのは理解してるとは言えませんねー。
    2008年12月8日 6:07