代码之家  ›  专栏  ›  技术社区  ›  thalm

ISerializable:在反序列化时分配现有对象

  •  3
  • thalm  · 技术社区  · 16 年前

    我们的任务非常简单,我们有一个对象图,其中每个对象(IDItem)都有一个唯一的ID。 对象图在客户机和服务器上存在两次。

    // 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构造函数中的以下内容不起作用,因为“this”标识符是只读的:

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

    你知道我们如何把一个现有的对象分配给反序列化的对象吗?

    致以最诚挚的问候, 塔尔姆

    2 回复  |  直到 16 年前
        1
  •  5
  •   LukeH    16 年前

    你呢 可以通过创建一个代理对象来实现 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!");
        }
    }
    
        2
  •  1
  •   rakuo15    16 年前

    你不能那样直接做。

    与其序列化整个对象而只包含一个字段,为什么不直接发送ID并在客户机和/或服务器上进行查找呢?如果我理解正确,服务器上已经存在该对象的实例。应该没有理由只为了再次查找同一个对象而需要传递该对象的剥离版本。

    如果ID是唯一的,并且与对象一起存储在某个集合中,那么将ID作为字符串或任何数据类型传递就足以在现有的对象集合中执行查找。