ISerializable: Assign an existing object on deserialization
our task is quite simple, we have an object graph where each object (IDItem) has a unique ID. The object graph exists two times, on the client and on the server machine.
Now we pass some serializable commands to the server. The command has as fields some of the IDItems. The IDItems implement the ISerializable interface and only store their ID in the SerializationInfo. Like:
// 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());
}
The problem is, how can we assign the existing object to the instance that the deserializer creates? Obviously something like the following in the ISerializable constructor does not work, because the 'this' identifier is read only:
//does not work
protected IDItem(SerializationInfo info, StreamingContext context)
{
this = GlobalObject.GetIDItem(info.GetString("ID"));
}
So any idea how we can Assign an existing object to the deserialized object?
Best Regards, thalm
You might be able to do it by creating a proxy object that implements IObjectReference
and performs the fake deserialization.
(Your proxy object would need to exist on both the client and server, and I suppose that your type versioning etc would also need to be exactly the same on both.)
[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!");
}
}
You can't do it directly like that.
Instead of serializing the whole object but only including one field, why not just send over the ID and do a lookup on the client and/or server? If I understand correctly, an instance of that object already exists on the server. There should be no reason why you would need to pass over a stripped version of that object just to look up the same object again.
If the ID is unique and stored in a collection somewhere along with the object, having the ID passed as a string, or whatever datatype it is, should be sufficient to perform a lookup in your existing collection of objects.
精彩评论