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