Domanda

Il nostro compito è abbastanza semplice, abbiamo un grafico oggetto in cui ogni oggetto (Iditem) ha un ID univoco. Il grafico dell'oggetto esiste due volte, sul client e sulla macchina del server.

Ora passiamo alcuni comandi serializzabili al server.Il comando ha come campi alcuni degli Iditem.Gli Iditem implementano l'interfaccia iserializzabile e memorizzano solo il loro ID nel serializzazioneNFO.Come:

// 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());
}
.

Il problema è, come possiamo assegnare l'oggetto esistente all'istanza che il deserializzatore crea?Ovviamente qualcosa come il seguente nel costruttore iserializzabile non funziona, perché l'identificatore 'questo' è solo lettura:

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

Allora qualsiasi idea come possiamo assegnare un oggetto esistente all'oggetto deserializzato?

Cordiali saluti, Thalm

È stato utile?

Soluzione

You potrebbe essere in grado di farlo creando un oggetto proxy che implementa IObjectReference ed esegue la deserializzazione falsa.

(il tuo oggetto proxy dovrebbe esistere su sia il client che il server, e suppongo che il tuo tipo di versioning ecc. Dovrebbe anche essere esattamente lo stesso su entrambi.)

[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!");
    }
}
.

Altri suggerimenti

Non puoi farlo direttamente così.

Invece di serializzare l'intero oggetto, ma solo un campo incluso, perché non inviare semplicemente l'ID e fare una ricerca sul client e / o sul server?Se capisco correttamente, esiste già un'istanza di quell'oggetto sul server.Non dovrebbe esserci alcuna ragione per cui dovresti passare su una versione spogliata di quell'oggetto solo per cercare di nuovo lo stesso oggetto.

Se l'ID è unico e memorizzato in una collezione da qualche parte insieme all'oggetto, con l'ID passata come una stringa, o qualunque sia il tipo di dati, dovrebbe essere sufficiente per eseguire una ricerca nella raccolta di oggetti esistenti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top