反序列化为List(Of T)时传递构造函数参数

时间:2019-05-25 20:33:32

标签: .net vb.net json.net office-interop

我需要通过JSON.Net对List(of T)进行序列化和反序列化,其中T是一个对象,其中包含无法序列化的引用。这是一个简化的版本:

Class MyObject

    Private ReadOnly _Parent As Word.Document

    Property Foo As String
    Property Bar As String

    Sub New(Parent As Word.Document, Foo As String, Bar As String)
        Me.New(Parent)
        Me.Foo = Foo
        Me.Bar = Bar
    End Sub

    Sub New(Parent As Word.Document)
        _Parent = Parent
    End Sub

    <JsonConstructor>
    Private Sub New()
    End Sub

    Function GetFile() As System.IO.FileInfo
        Return New FileInfo(_Parent.FullName)
    End Function

End Class

对于这个故事,我将JSON字符串(序列化列表)存储在Word文档变量中。打开文档时,我将字符串取反序列化,然后我希望能够设置_Parent字段来引用同一文档。 困难不是知道_Parent应该参考什么,而是要设置参考。请注意,我想保留它Private,但是如有必要,可以对其进行读写。

是否有一种方法告诉JSON.Net使用New(Parent As Word.Document)构造函数,并通过Parent传递此JsonConvert.DeserializeObject(Of T)参数? 还是至少要告诉JSON.Net,我想在反序列化之前/之后运行特定的Sub?

一个简单的绕过方法是在下面使用构造函数,但是我不喜欢它,因为如果同时打开多个文档,它可能会弄乱。

<JsonConstructor>
Private Sub New()
    _Parent = ThisWordApp.ActiveDocument
End Sub

我对C#中的响应很好。

1 个答案:

答案 0 :(得分:2)

您可以采用从this answer Pass additional data to JsonConverter 的第二种方法,并创建一个CustomCreationConverter(Of MyObject),它使用{{ 1}}传递给转换器本身。

首先,定义以下转换器:

MyObject

然后您可以按以下方式使用它:

Word.Document

注意:

  • 此解决方案的另一个优点是,您不再需要Class MyObjectConverter Inherits CustomCreationConverter(Of MyObject) Private ReadOnly _Parent As Word.Document Sub New(Parent As Word.Document) If Parent Is Nothing Then Throw New ArgumentNullException("Parent") End If _Parent = Parent End Sub Overrides Function Create(objectType as Type) As MyObject Return New MyObject(_Parent) End Function End Class 的{​​{1}}构造函数,并且可以完全删除它。

  • 此转换器永远不会在使用JsonConverterAttribute的编译时应用,它只能在给定已知Dim settings = New JsonSerializerSettings() With { .Converters = { new MyObjectConverter(document) } } Dim list = JsonConvert.DeserializeObject(Of List(Of MyObject))(jsonString, settings) (在上面代码示例中的<JsonConstructor> Private Sub New()变量的情况下,在运行时构造) )。

演示小提琴here