そのインターフェースを持たないクラスをシリアル化できるようですので、その目的がわかりません。
4 に答える
ISerializable
通常はBinaryFormatter
(そしておそらくリモーティングの目的で)カスタムバイナリシリアル化を提供するために使用されます。これがないと、次のようなフィールドが使用されます。
- 非効率的な; 実行時に効率を上げるためだけに使用されるが、シリアル化のために削除できるフィールドがある場合(たとえば、シリアル化すると辞書が異なって見える場合があります)
- 非効率的な; 必要なフィールドの場合でも、多くの追加のメタデータを含める必要があります
- 無効; シリアル化できないフィールドがある場合(マークを付けることはできますが、イベントデリゲートなど
[NonSerialized]
) - もろい; これで、シリアル化はフィールド名にバインドされますが、フィールドは実装の詳細であることが意図されています。難読化、シリアル化、および自動的に実装されたプロパティも参照してください。
実装ISerializable
することにより、独自のバイナリシリアル化メカニズムを提供できます。これに相当するxmlは、などIXmlSerializable
で使用されていることに注意してください。XmlSerializer
DTOの目的でBinaryFormatter
は、避ける必要があります。xml(viaXmlSerializer
またはDataContractSerializer
)やjsonのようなものは、プロトコルバッファのようなクロスプラットフォーム形式と同様に適切です。
完全を期すために、protobuf-netにはISerializable
(多くのコードを記述せずにポータブルバイナリ形式を使用できるようにする)ためのフックが含まれていますBinaryFormatter
が、とにかくここでの最初の選択肢ではありません。
クラスは、次の2つの方法のいずれかで.NETでシリアル化できます。
- クラスをマークし、属性でシリアル化したくない
SerializableAttribute
すべてのフィールドを装飾します。(Marc Gravellが指摘しているように、オブジェクトのフォーマットに通常使用されるクラスは、特にマークされていない限り、すべてのフィールドを自動的にシリアル化します。)NonSerialized
BinaryFormatter
ISerializable
ISerializable
完全にカスタムのシリアル化のためのインターフェースの実装。
前者は、宣言に属性をマークするだけであるため、使用が簡単ですが、その能力には制限があります。後者の方が柔軟性が高くなりますが、実装にかなりの労力がかかります。どちらを使用するかは、コンテキストによって異なります。
後者(ISerializable
)とその使用法については、MSDNページのインターフェイスから引用しました。
シリアル化される可能性のあるクラスはすべて、SerializableAttributeでマークする必要があります。クラスがシリアル化プロセスを制御する必要がある場合は、ISerializableインターフェイスを実装できます。Formatterは、シリアル化時にGetObjectDataを呼び出し、提供されたSerializationInfoにオブジェクトを表すために必要なすべてのデータを入力します。Formatterは、グラフ内のオブジェクトのタイプを使用してSerializationInfoを作成します。自身のプロキシを送信する必要があるオブジェクトは、SerializationInfoのFullTypeNameメソッドとAssemblyNameメソッドを使用して、送信される情報を変更できます。
クラス継承の場合、ISerializableを実装する基本クラスから派生したクラスをシリアル化することができます。この場合、派生クラスは、GetObjectDataの実装内でGetObjectDataの基本クラス実装を呼び出す必要があります。そうしないと、基本クラスのデータはシリアル化されません。
これISerializable
を使用すると、オブジェクトにカスタムメソッドを記述して、バイナリシリアル化を行うときにシリアル化を引き継ぎ、BinaryFormatterで使用されるデフォルトのアプローチとは異なる方法でオブジェクトをシリアル化できます。
つまり、デフォルトのアプローチでオブジェクトをシリアル化する方法とは異なる方法でシリアル化する場合は、ISerializableを実装して完全に制御できます。ISerializableと連携して、実装する必要のあるカスタムコンストラクターもあることに注意してください。
XmlSerializationはもちろんプロパティのみを使用します。ISerializableはXMLシリアル化とは何の関係もありません。
コメントをくれたMarcとPopに感謝します、私は私の最初の答えに少し急いでいました。
オブジェクトを「トランスポータブル」にするには、オブジェクトをシリアル化する必要があります。たとえば、.NET RemotingまたはWebサービスを使用してオブジェクトデータを転送する場合は、オブジェクトデータをシリアル化するメソッドを提供して、オブジェクトインスタンスをオブジェクトの忠実度の高い表現を表すトランスポータブル形式に縮小する必要があります。
次に、シリアル化された表現を取得し、それを別のマシンなどの別のコンテキストに転送して、元のオブジェクトを再構築することもできます。
インターフェイスを実装する場合ISerializable
、クラスは、インターフェイスに含まれるGetObjectDataメソッドと、SerializationInfoのインスタンスとStreamingContextのインスタンスの2つのパラメーターを受け入れるように特化された専用のコンストラクターを提供する必要があります。
クラスがオブジェクトの状態をきめ細かく制御する必要がない場合は、[Serializable]
属性を使用できます。シリアル化プロセスをより詳細に制御する必要があるクラスは、ISerializableインターフェイスを実装できます。