在自定义反序列化构造函数中添加字段

时间:2014-02-04 16:10:34

标签: vb.net serialization

我有一个实现ISerializable接口的类,有一个保存和检索的私有字段:

Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
    _name= info.GetString("_name")
End Sub

现在,我想添加一个新的私有字段,但由于之前不存在,当我尝试打开一个序列化对象时,在尝试获取此字段时,在自定义反序列化构造函数中会出现异常。我提出的解决方案是使用Try ... Catch块,如下所示:

Protected Sub New(ByVal info As SerializationInfo, _
                 ByVal context As StreamingContext)
    _name= info.GetString("_name")
    Try
       _active= info.GetBoolean("_active")
    Catch ex As Exception
        _active= False
    End Try
End Sub

它有效,但对我来说似乎有些混乱,而且因为我必须为我想要添加的每个新字段添加一个新的Try ... Catch块。 有没有更好的方法呢?

谢谢!

修改: 在this answer t0mm13b中说“有一种更简洁的方法可以在2.0+以上”完成此操作。关于他在说什么的任何想法?

1 个答案:

答案 0 :(得分:1)

没有内置方法可以让您首先确定特定值是否存在(例如Exists)。如果该值不存在,则还没有Get...方法只返回Nothing(例如TryGet)。但是,可以避免可能出现异常的一种方法是使用For Each循环来遍历SerializationInfo集合中的所有值。例如:

For Each i As SerializationEntry In info
    Select Case i.Name
        Case "_name"
            _name = DirectCast(i.Value, String)

        ' ...
    End Select
Next

注意:您可能会惊讶于您可以在For Each对象上使用SerializationInfo循环,因为它没有实现IEnumerable接口(也不是通用的等价物)。但是,VB.NET中的For Each实际上适用于具有公共GetEnumerator方法的任何对象。因此,即使它导致一些混淆,对象在技术上也不需要实现IEnumerable,以便您使用For Each循环遍历它们。由于SerializationInfo确实公开了公共GetEnumerator方法,因此您可以使用For Each循环遍历它。