考虑这个类:
[Persistable]
public sealed class FileMoveTask : TaskBase
{
[PersistMember]
public string SourceFilePath { get; private set;}
[PersistMember]
public string DestFilePath { get; private set;}
public FileMoveTask(string srcpath, string dstpath)
{
this.SourceFilePath = srcpath;
this.DestFilePath = dstpath;
//possibly other IMPORTANT initializations
}
//code
}
我能坚持这个类的对象,通过序列化所有属性成员PersistMember
。 但我现在面临反序列化过程的一些问题(设计问题)。 特别是,问题出在“其他可能的重要初始化”,这可能会在构造函数中存在,而程序员可能决定不进行一些成员持久化(即不添加PersistMember
他们)可能是因为这没有任何意义。
在这种情况下,我怎么会反序列化对象完全相同的状态,因为它是? 我想,这个问题归结为:我怎么会调用非默认构造函数,传递相同的参数给它,这是之前通过呢? 有没有办法做到这一点? 我们可以做一些规则可以由编译器(排序元编程)执行呢? 构造属性可以帮助吗?
您可以解决两种方式。 使用约定优于配置(命名构造函数参数的属性,不包括默认构造函数):
[Persistable]
public sealed class FileMoveTask : TaskBase
{
[PersistMember]
public string SourceFilePath { get; private set;}
[PersistMember]
public string DestFilePath { get; private set;}
public FileMoveTask(string sourceFilePath, string destFilePath)
{
this.SourceFilePath = srcpath;
this.DestFilePath = dstpath;
//possibly other IMPORTANT initializations
}
//code
}
明确你的属性标记构造函数的参数,并搜索已标记的构造函数:
[Persistable]
public sealed class FileMoveTask : TaskBase
{
[PersistMember]
public string SourceFilePath { get; private set;}
[PersistMember]
public string DestFilePath { get; private set;}
public FileMoveTask([PersistMember("SourceFilePath")]string srcpath, [PersistMember("DestFilePath")]string dstpath)
{
this.SourceFilePath = srcpath;
this.DestFilePath = dstpath;
//possibly other IMPORTANT initializations
}
//code
}
属性或参数名称没有用了就知道要设置的属性,但要知道调用构造函数时所使用的从序列化的数据信息。
解决这个问题最简单的方法是使用现有的公知技术。 例如,看看那些在.NET框架中使用(你会发现巨大的差异是什么)其他序列化机制。
例如,在BinaryFormatter的 , SoapFormatter和DataContractSerializer的使用对于反序列化对象以下技术:
- 获得“原始”通过调用对象FormatterServices.GetUnitializedObject
- 调用构造的对象在单独序列化前方法(通过检查标记方法OnSerializingAttribute )。
- 反序列化对象的状态(通过检查相应的属性,了解哪些字段串行应该跳过哪些字段应该反序列化)。
- 呼叫序列化后方法上反序列化对象(通过检查标记方法OnSerializedAttribute )。
另一方面XmlSerializer的使用完全不同的算法:它要求应作为“预系列化”和“序列化后”的步骤参数的构造函数。
所以我的观点是,它完全取决于串行器的类型和其执行情况。 而在仍然需要从两个串行的作者和串行的消费者一些心力。
所以我强烈建议使用现有技术中的一种,但不是发明轮子(如添加一些其他的自定义属性还原对象的状态)。 你甚至可以使用现有属性来简化从.NET序列化设施,以自定义序列化机制的迁移(以及使用额外的属性,如NonSerializableAttrubite )。