[Serializable]とは何ですか。いつ使用する必要がありますか。


317

一部のクラスが[Serializable]属性を使用していることがわかりました。

  • それは何ですか?
  • いつ使用すべきですか?
  • どのようなメリットがありますか?



1
これが私が見つけた実用的な使用法の説明です。
Nipuna

回答:


368

それは何ですか?

.Netフレームワークアプリケーションでオブジェクトを作成する場合、データがメモリに格納される方法を考慮する必要はありません。.Net Frameworkが自動的に処理します。ただし、オブジェクトのコンテンツをファイルに保存したり、オブジェクトを別のプロセスに送信したり、ネットワークを介して送信したりする場合は、別の形式に変換する必要があるため、オブジェクトの表現方法を考慮する必要があります。この変換はSERIALIZATIONと呼ばれます。

シリアライゼーションの使用

シリアライゼーションにより、開発者はオブジェクトの状態を保存し、必要に応じてオブジェクトを再作成して、オブジェクトのストレージとデータ交換を提供できます。開発者はシリアライゼーションを通じて、Webサービスを介してオブジェクトをリモートアプリケーションに送信する、オブジェクトをあるドメインから別のドメインに渡す、ファイアウォールを介してXML文字列として渡す、セキュリティやユーザー固有のメンテナンスを行うなどのアクションを実行できます。アプリケーション間の情報。

SerializableAttribute型に適用して、この型のインスタンスをシリアル化できることを示します。SerializableAttributeクラスも実装している場合でも適用ISerializableがシリアル化プロセスを制御するインターフェイスます。

型でシリアル化プロセスをオーバーライドするインターフェイスをSerializableAttribute実装しない限り、でマークされた型のすべてのパブリックフィールドとプライベートフィールドはデフォルトでシリアル化されますISerializable。デフォルトのシリアル化プロセスでは、でマークされたフィールドが除外されますNonSerializedAttribute。シリアル化可能な型のフィールドに、特定の環境に固有のポインター、ハンドル、またはその他のデータ構造が含まれていて、異なる環境で意味のある再構成ができない場合は、適用することができますNonSerializedAttribute、そのフィールドすること。

MSDNを参照をしてください。

編集1

何かをシリアライズ可能としてマークしない理由

データを転送または保存する場合、必要なデータのみを送信または保存する必要があります。そのため、転送の遅延やストレージの問題が少なくなります。したがって、シリアル化するときに不要なデータのチャンクをオプトアウトできます。


1
@dwbartzあなたの質問はここに リンクされています
jayasurya_j

2
すばらしい説明です。これをMSDNの属性に追加するとよいでしょう=)
Martea

@jayasurya_j残念ながら、受け入れられた回答はプライベートな部分
Alexander

1
良い説明
ザキルHC

42

[Serializable]属性のいくつかの実用的な用途:

  • バイナリシリアル化を使用してオブジェクトの状態を保存する。アプリケーション内のオブジェクトインスタンス全体を非常に簡単にファイルまたはネットワークストリームに「保存」してから、逆シリアル化して再作成できますBinaryFormatter。System.Runtime.Serialization.Formatters.Binary のクラスを確認してください。
  • オブジェクトのインスタンスをクリップボードに保存できるClipboard.SetData()クラスの記述-シリアライズできないクラスはクリップボードに配置できません。
  • .NET Remotingと互換性のあるクラスを記述します。通常、アプリケーションドメイン間で渡すクラスインスタンス(から拡張されるものを除くMarshalByRefObject)は、シリアル化可能でなければなりません。

これらは、私が遭遇した最も一般的な使用例です。


42

元の質問はSerializableAttributeに関するものでしたので、この属性はBinaryFormatterまたはSoapFormatterを使用する場合にのみ適用されることに注意してください。

いつそれを使用するのか、そしてその実際の目的は何かについて、本当に細部に注意を払わない限り、それは少し混乱します。

XMLまたはJSONのシリアル化とは何の関係もありません。

SerializableAttributeと共に使用されるのは、ISerializableインターフェイスとSerializationInfoクラスです。これらもBinaryFormatterまたはSoapFormatterでのみ使用されます。

BinaryまたはSoapを使用してクラスをシリアル化するつもりがない限り、クラスを[Serializable]としてマークしないでください。XMLおよびJSONシリアライザーは、その存在すら認識していません。


16
「XMLやJSONのシリアル化とは何の関係もありません」-ありがとうございます!最後に、この属性の有無にかかわらず、クラスをXMLに楽しくシリアル化できる理由の説明
userSteve

1
これのソースはありますか?
Michiel van Oosterhout

「XMLおよびJSONシリアライザーは、その存在すら認識していません」。私はそれについて知りません。WCFを介してクラスをJSON形式でフォーマットすると、クラスがの場合、プロパティ名の前に下線が付きSerializable、属性が削除されたときはありませんでした。したがって、干渉が発生する可能性があります。
イェンス、

@Jens私が正しく理解した場合、JSON.netはそれについて少し気にしませんが、asp.netはこの動作を少し変更します。JsonObject / JsonProperty属性でこれを回避できると思います。
ベース

29

シリアル化は、オブジェクトをバイトストリームに変換して、オブジェクトを格納したり、メモリ、データベース、またはファイルに送信したりするプロセスです。

シリアル化のしくみ

この図は、シリアル化の全体的なプロセスを示しています。

ここに画像の説明を入力してください

オブジェクトは、データだけでなく、バ​​ージョン、カルチャ、アセンブリ名などのオブジェクトのタイプに関する情報を運ぶストリームにシリアル化されます。そのストリームから、データベース、ファイル、またはメモリに保存できます。

msdnの詳細。



14

連載

シリアライゼーションは、オブジェクトまたはオブジェクトのセットのグラフをストリームに変換するプロセスであり、バイナリシリアライゼーションの場合はバイト配列です。

シリアライゼーションの使用

  1. オブジェクトの状態をファイルやデータベースなどに保存し、後で使用すること。
  2. 同じマシン上のあるプロセスから別のプロセス(アプリドメイン)にオブジェクトを送信し、別のマシンで実行されているプロセスに有線で送信すること。
  3. メインオブジェクトでの作業中に、バックアップとして元のオブジェクトのクローンを作成します。
  4. オブジェクトのセットをシステムのクリップボードに簡単にコピーして、同じまたは別のアプリケーションに貼り付けることができます

以下は、オブジェクトのシリアル化中に使用されるいくつかの便利なカスタム属性です

[Serializable] ->オブジェクトの直列化可能をマークするときに使用されます [NonSerialized] ->オブジェクトのフィールドを直列化しない場合に使用されます。 [OnSerializing] ->オブジェクトのシリアル化中に何らかのアクションを実行したい場合に使用されます [OnSerialized] ->オブジェクトをストリームにシリアル化した後に何らかのアクションを実行したい場合に使用されます。

以下はシリアライズの例です

[Serializable]
    internal class DemoForSerializable
    {
        internal string Fname = string.Empty;
        internal string Lname = string.Empty;

        internal Stream SerializeToMS(DemoForSerializable demo)
        {
            DemoForSerializable objSer = new DemoForSerializable();
            MemoryStream ms = new MemoryStream();
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, objSer);
            return ms;
        }

        [OnSerializing]
        private void OnSerializing(StreamingContext context) {
            Fname = "sheo";
            Lname = "Dayal";
        }
        [OnSerialized]
        private void OnSerialized(StreamingContext context)
        {
       // Do some work after serialized object
        }

    }

これが呼び出しコードです

class Program
    {
        string fname = string.Empty;
        string Lname = string.Empty; 

       static void Main(string[] args)
        {
            DemoForSerializable demo = new DemoForSerializable();

            Stream ms = demo.SerializeToMS(demo);
            ms.Position = 0;

            DemoForSerializable demo1 = new BinaryFormatter().Deserialize(ms) as DemoForSerializable;

            Console.WriteLine(demo1.Fname);
            Console.WriteLine(demo1.Lname);
            Console.ReadLine();
        }

    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.