代码之家  ›  专栏  ›  技术社区  ›  Bill Yang

OnSerializingAttribute与ISerializable

  •  6
  • Bill Yang  · 技术社区  · 16 年前

    我正在阅读有关msdn: http://msdn.microsoft.com/en-us/library/ty01x675%28VS.80%29.aspx

    它提到有两种实现自定义序列化的方法:
    1,使用 OnDeserializedAttribute, OnDeserializingAttribute, OnSerializedAttribute, OnSerializingAttribute
    2、实现 ISerializable 界面

    根据msdn,方法1是“最佳实践和最简单的”,但我无法理解这两种方法是如何甚至是相同的事情。据我所知, OnSerializing|OnSerialized|etc 属性允许您将方法挂钩到序列化的特定阶段,而 可分割的 接口允许您直接修改进入和退出的内容 SerializationInfo . 这是正确的吗?

    为了将我的困惑放到上下文中,您如何实现OnSerializing来序列化不同名称下的对象字段?如下代码:

    public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("i", n1);
        info.AddValue("j", n2);
        info.AddValue("k", str);
    }
    

    更新 :尽管Frederik Gheysels的回答不完全正确(在OnSerializing/OnDeserializing属性和ISerializable接口中都需要用Serializable进行修饰),但他确实指出OnSerializing/OnDeserializing属性是ISerializable的补充,因此我接受他的回答。T

    1 回复  |  直到 16 年前
        1
  •  5
  •   Frederik Gheysels    16 年前

    OnSerializing / OnDeserializing 是对的补充 ISerializable SerializableAttribute .

    换言之: 串行化 / 反序列化 不是 可分割的 序列化属性 .

    这两个属性( 串行化 / 缩聚 )允许您在对象序列化或反序列化时采取控制/执行额外操作。但是,为了能够做到这一点,应用这些属性的类型必须是可序列化的(从而实现 可分割的 接口,或用可序列化属性修饰)。

    在您所指的msdn文章中也这样说: -OnSerializing和OnDeserializing用于在序列化期间和之后“更正”数据。

    你可以很容易地测试它。 创建这样的类型,并尝试将其序列化:

    public class Foo
    {
        private int _bar = 5;
    
        [OnSerializing]
        public void OnSerializeFoo( StreamingContext context )
        {
            _bar = 10;
        }
    }
    

    请注意,类型不实现 可分割的 也不是用 序列化属性 . 尝试序列化该类型的实例,您将面临 SerializationException ,因为 Foo 不可序列化。

    因此,可以使用这些属性(OnSerializing、OnDeserializing)来实现在序列化或反序列化特定类型的实例时应该执行的附加逻辑。