OnSerializingAttribute vs ISerializable

时间:2009-09-22 22:19:21

标签: c# .net serialization

我正在阅读有关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属性允许您将方法挂钩到序列化的特定阶段,而ISerializable接口允许您直接修改进出SerializationInfo的内容。这是对的吗?

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

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

更新:虽然Frederik Gheysels的答案并不完全正确(使用Serializable进行装饰是OnSerializing / OnDeserializing属性和ISerializable接口的先决条件),但他确实指出OnSerializing / OnDeserializing属性是意味着是ISerializable的补充,所以我接受他在这一点上的答案。

1 个答案:

答案 0 :(得分:5)

OnSerializing / OnDeserializing是对ISerializableSerializableAttribute的补充。

换句话说:OnSerializing / OnDeserializing不是ISerializableSerializableAttribute的替代品。

这两个属性(OnSerializing / OnDeserializing)允许您在序列化或反序列化对象时控制/执行额外操作。但是,为了能够执行此操作,应用这些属性的类型必须是可序列化的(因此实现ISerializable接口,或使用Serializable属性修饰)。

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

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

public class Foo
{
    private int _bar = 5;

    [OnSerializing]
    public void OnSerializeFoo( StreamingContext context )
    {
        _bar = 10;
    }
}

请注意,该类型未实现ISerializable,也未使用SerializableAttribute进行修饰。 尝试序列化该类型的实例,您将面临SerializationException,因为Foo不可序列化。

因此,您可以使用这些属性(OnSerializing,OnDeserializing)来实现在序列化或反序列化某个类型的实例时应执行的其他逻辑。