Iserializable:既存のオブジェクトをデシリアライゼーションに割り当てます
-
13-09-2020 - |
質問
私たちのタスクは非常に簡単です、私たちは各オブジェクト(iditem)が一意のIDを持つオブジェクトグラフを持っています。 オブジェクトグラフは、クライアント上およびサーバーマシン上で2回存在します。
今度はシリアライズ可能なコマンドをサーバーに渡します。このコマンドには、IDITEMのいくつかがフィールドとしてあります。IDITEMSはISERIAIZABLEインタフェースを実装し、それらのIDをSerializationInfoにしか保存します。のような:
// The method called when serializing a IDItem.
void GetObjectData(SerializationInfo info, StreamingContext context)
{
// Instead of serializing this object, just save the ID
info.AddValue("ID", this.GetID());
}
.
問題は、既存のオブジェクトをデシリアライザが作成するインスタンスにどのように割り当てることができますか?「この」識別子が読み取り専用であるため、iserializableコンストラクターで次のようなものは動作しません。
//does not work
protected IDItem(SerializationInfo info, StreamingContext context)
{
this = GlobalObject.GetIDItem(info.GetString("ID"));
}
.
だから既存のオブジェクトをデシリアル化オブジェクトに割り当てることができる方法はどのようにしていますか?
Thalm
解決
あなたかもしれませんが IObjectReference
と偽の逆シリアル化を実行します。
(プロキシオブジェクトはクライアントとサーバーの両方に存在する必要があります。また、タイプのバージョン管理などが両方でまったく同じである必要があると思います。)
[Serializable]
public class Example : ISerializable
{
// ...
void ISerializable.GetObjectData(
SerializationInfo info, StreamingContext context)
{
info.SetType(typeof(ExampleDeserializationProxy));
info.AddValue("ID", this.GetID());
}
}
// ...
[Serializable]
public class ExampleDeserializationProxy : IObjectReference, ISerializable
{
private readonly int _id;
private ExampleDeserializationProxy(
SerializationInfo info, StreamingContext context)
{
_id = info.GetInt32("ID");
}
object IObjectReference.GetRealObject(StreamingContext context)
{
return GlobalObject.GetIDItem(_id);
}
void ISerializable.GetObjectData(
SerializationInfo info, StreamingContext context)
{
throw new NotSupportedException("Don't serialize me!");
}
}
. 他のヒント
あなたはそのように直接することはできません。
オブジェクト全体をシリアル化する代わりに、1つのフィールドを含めているだけでなく、IDを送信するだけでなく、クライアントやサーバーで検索を行いますか?私が正しく理解した場合、そのオブジェクトのインスタンスはすでにサーバーに存在します。同じオブジェクトをもう一度検索するためだけにそのオブジェクトのストリップバージョンを渡す必要がある理由はありません。
IDが一意で、オブジェクトとともにどこかにコレクションに保存されている場合は、IDが文字列として渡されたもの、またはそれがどんなデータ型であっても、既存のオブジェクトのコレクションにルックアップを実行するのに十分です。