我在vb.net Web API中有一个类,有时需要序列化。因此,我将该班级标记为<Serializable>
。精细。但是,它在许多级别上都有许多子类。其中一些被遗漏了(或由于添加了新的而被遗漏了)。如果该元素为null,那很好,但是如果不是,那么序列化将失败:
[SerializationException]在程序集“ Foo”中键入“ Foo.Bar”, 版本= 1.0.0.4866,文化=中性,PublicKeyToken =空'不是 标记为可序列化。
由于序列化是在后台使用的,因此为了保存状态以便以后恢复,并非总是会立即注意到它。
序列化正在vb.net中使用BinaryFormatter
有没有办法标记父类,使得所有子类(及其子类,等等)也必须可序列化?我宁愿为此遇到编译时错误,而不是运行时错误。
我从一些最初的答复中意识到,我的问题还不够清楚。我不应该使用 parents 和 children 这两个词,因为我不太关注作为类成员继承的类
<Serializable()>
Class MyObj
Public Property foo as new Foo
Public Property bar as new Bar
end Class
我曾期望这会要求Foo
和Bar
可序列化,因为否则MyObj
不是
答案 0 :(得分:6)
不,您不能简单地强制执行此操作。最好的选择是添加一个单元测试,该单元测试通过反射来发现子类并检查它们是否具有属性,如果缺少该属性,则失败。
但是,我也建议不要使用BinaryFormatter
。我见过 way 太多的人为此受了伤害-它将类型和序列化数据紧密地联系在一起。 .NET中有很多更好的序列化选项,适用于基于文本和二进制的序列化格式。
答案 1 :(得分:1)
在VB.NET中,没有办法让派生类从其基类继承属性,更不用说强制它了。 .NET也无法在运行时动态地向类添加属性。另外,BinaryFormatter
无法覆盖它,因此它可以序列化不可序列化的类型或强制其在基类中搜索属性。因此,您别无选择。以下是一些替代方法:
BinaryFormatter
。还有许多其他更好,更多的标准串行器,它们没有相同的限制。ISerializable
个成员实现MustOverride
,从而强制每个派生类提供一个实现(当该类实现该接口时,BinaryFormatter
将使用该接口来执行序列化即使班级没有SerializableAttribute
)SerializableAttribute
的类型,则理论上可以动态声明一个新类,该类继承给定对象的类中的内容,不会覆盖任何内容,但会添加SerializableAttribute
。然后,创建该运行时生成类型的新对象,将数据从原始对象动态复制到该新对象,然后序列化该副本。但是,这不仅是一个可怕的想法,而且可能很难使自动生成的类具有完全相同的名称(包括完整的程序集名称),以致BinaryFormatter
会将其视为完全相同。类型。 BinaryFormatter
非常脆弱,因此让它与动态创建的类型一起使用是不切实际甚至是不可能的,这不会令我感到震惊。答案 2 :(得分:1)
Inherited
的{{1}}属性。
创建您的自定义Serializable属性只是为了覆盖AttributeUsage
值。并使用它代替Inherited
。
[Serializable]
属性的内部实现:
[Serializable]
此处 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct |
AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false)]
public sealed class SerializableAttribute : Attribute
{
//
// Summary:
// Initializes a new instance of the System.SerializableAttribute class.
public SerializableAttribute();
}
设置为Inherited
;这意味着派生类不能继承此属性。
只需覆盖此属性并使用您的自定义属性即可。
您还可以在运行时验证子类中某些属性的存在。
通过引发自定义异常,可以帮助您确定确切的错误。
false