使用Serializable属性和实现ISerializable之间有什么区别?


Answers:


41

当您使用SerializableAttribute属性时,您将在编译时将属性放在字段上,以便在运行时,序列化工具将通过对类/模块/程序集进行反射来知道要基于属性序列化的内容类型。

[Serializable]
public class MyFoo { … }

上面指出了序列化工具应该序列化整个class MyFoo,而:

public class MyFoo
{
    private int bar;

    [Serializable]
    public int WhatBar
    {
       get { return this.bar; }
    }
}

使用该属性,您可以有选择地选择需要序列化的字段。

当实现ISerializable接口时,通过覆盖(并通过提供form的构造函数)可以有效地使用自定义版本覆盖序列化,从而可以更好地控制数据的序列化。GetObjectData SetObjectDataMyFoo(SerializationInfo info, StreamingContext context)

另请参见StackOverflow上的此自定义序列化示例。它显示了如何保持序列化与序列化数据的不同版本向后兼容。

希望这可以帮助。


11
可以在哪个版本的.NET中将该Serializable属性添加到属性中?MSDN说,它只能应用于类,结构,枚举和委托。
hangy 2013年

5
没有。可序列化属性不能应用于属性,只能应用于类,结构和枚举以及委托声明。
丹尼尔·莱森

3
相反:当用修饰类时SerializableAttribute,可以将成员标记NonSerializedAttribute为要跳过,就像多人(和MSDN)所说的那样,当在不同的环境中重构某个对象没有意义时,最好不要序列化它。 ..
nurchi 2014年

20

SerializableAttribute指示做框架默认序列化过程。如果您需要更多控制权,则可以实现ISerializable接口。然后,您将使用自己的代码来序列化该GetObjectData方法中的SerializationInfo对象,并更新传递给它的对象。


4
如果实现ISerializable,则实现反序列化构造函数也是习惯(甚至可能是必需的):protected SomeClass(SerializationInfo info,StreamingContext context)
jrista 2010年

18
请注意,即使实现ISerializable接口,仍必须标记类[Serializable]。
亚当李尔

3

ISerializable界面可让您实现除默认值以外的自定义序列化。实现ISerializable接口时,必须重写GetObjectData方法,如下所示

public void GetObjectData (SerializationInfo serInfo, 
                                    StreamingContext streamContext)
{
   // Implement custom Serialization
}

1

ISerialize强制您手动实现序列化逻辑,同时使用Serializable属性进行标记(您是不是要这么做?)会告诉Binary序列化器此类可以序列化。它将自动执行。


0

从ISerializable继承可让您自定义实现(反序列化)。仅使用Serializable属性时,(反)序列化只能由属性控制,灵活性较差。


反序列化通过反序列化构造函数进行处理。请参阅我对segfaults答案的评论。
jrista'3
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.