4

私たちのタスクは非常に単純です。各オブジェクト (IDItem) が一意の ID を持つオブジェクト グラフがあります。オブジェクト グラフは、クライアントとサーバー マシンの 2 回存在します。

ここで、いくつかのシリアライズ可能なコマンドをサーバーに渡します。このコマンドには、いくつかの IDItems がフィールドとして含まれています。IDItems は ISerializable インターフェイスを実装し、それらの 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());
}

問題は、デシリアライザーが作成するインスタンスに既存のオブジェクトをどのように割り当てることができるかということです。「this」識別子は読み取り専用であるため、ISerializable コンストラクターの次のようなものは明らかに機能しません。

//does not work   
protected IDItem(SerializationInfo info, StreamingContext context)
{
    this = GlobalObject.GetIDItem(info.GetString("ID"));
}

では、既存のオブジェクトをデシリアライズされたオブジェクトに割り当てる方法はありますか?

敬具、タルム

4

2 に答える 2

5

偽の逆シリアル化を実装して実行するプロキシ オブジェクトを作成することで、それを実行できる場合があります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!");
    }
}
于 2010-07-09T15:29:59.620 に答える
1

そのように直接行うことはできません。

オブジェクト全体をシリアル化して 1 つのフィールドのみを含める代わりに、ID を送信してクライアントやサーバーでルックアップを実行してみませんか? 私の理解が正しければ、そのオブジェクトのインスタンスはサーバー上に既に存在します。同じオブジェクトを再度検索するためだけに、そのオブジェクトの削除されたバージョンを渡す必要がある理由はありません。

ID が一意であり、オブジェクトと共にコレクションのどこかに保存されている場合、ID を文字列またはデータ型として渡せば、オブジェクトの既存のコレクションでルックアップを実行するのに十分なはずです。

于 2010-07-09T14:18:31.140 に答える