在.NET开发中,经常会遇到需要序列化和反序列化对象的情况。但是,当对象集合中包含派生类实例时,序列化错误常常发生。这是因为XmlSerializer不知道如何处理这些未知的派生类型。虽然可以通过注册派生类型来解决这个问题,但这种做法不支持未来的可扩展性。每当有新的派生类出现时,都需要手动编写自定义序列化器,这在快速开发中是不可接受的。
为了解决这个问题,创建了一个简单的服务,它利用XmlSerializer的构造函数,通过包含额外的类型数组和可以装饰到类声明上的自定义属性,来优雅地支持快速开发。
使用这段代码非常简单,只需要两步。首先,需要在类声明上添加自定义属性SerializableExtraType。其次,在进行常规的序列化和反序列化操作时,传入SerializableExtraTypes跟踪的extraTypes参数。
静态的serialize和deserialize方法是这个类的一部分。按照以下方式装饰类:
C#
[Serializable]
// 示例:注册类及其所有派生类
[SerializableExtraType(typeof(Foo))]
// 示例:注册类与无关类
[SerializableExtraType(typeof(SomethingElse))]
// 示例:在同一属性中注册多个类
[SerializableExtraType(new Type[] {
typeof(ClassOne),
typeof(ClassTwo) })]
public class Foo {
public Foo() { }
}
在.NET中,所有需要序列化的类都需要[Serializable]属性。这里只是添加了一个额外的[SerializableExtraType(Type type)]属性。任何标准的序列化规则仍然适用。不需要为Foo的任何派生类添加属性,因为它会在所有派生类中继承。这意味着可以将属性添加到一个抽象基类上,所有的类都会被注册。这里给出了一个示例,将Foo注册为自己以及几个其他类型。这展示了使用[SerializableExtraType]属性的所有可能的变体。
以下是一个包含Foo及其派生对象集合的对象的序列化和反序列化示例:
C#
string s = SerializableExtraTypes.Serialize(someObject, typeof(Foo));
object o = SerializableExtraTypes.Deserialize(strSomeObject, typeof(SomeObject), typeof(Foo));