2012-10-22 42 views
3

我有一個遞歸數據結構。類似...自定義多態Newtonsoft JSON解串器

Public Class Comparison 
    Property Id As Integer 
End Class 

Public Class SimpleComparison 
    Inherits Comparison 
    Property Left As String 
    Property Right As String 
End Class 

Public Class ComplexComparison 
    Inherits Comparison 
    Property Left As Comparison 
    Property Right As Comparison 
End Class 

我需要從JSON反序列化到此。

如您所見,確定使用ComplexComparison還是SimpleComparison的唯一方法是確定.Left值是字符串還是對象。 (NB要麼他們會同時爲字符串或兩個對象)

所以,我正在寫一個自定義的轉換器,這至今都得到了...

Public Class ComparisonConverter 
    Inherits Newtonsoft.Json.JsonConverter 
    ''<Snip> 
Public Overrides Function ReadJson(reader As Newtonsoft.Json.JsonReader, objectType As Type, existingValue As Object, serializer As Newtonsoft.Json.JsonSerializer) As Object 
    Dim obj As JObject = TryCast(serializer.Deserialize(Of JToken)(reader), JObject) 
    If obj IsNot Nothing Then 
      ''We''ve got something to work with 
     Dim Id As Integer = obj("Id").ToObject(Of Integer)() 

      ''Check if we''re instantiating a simple or a complex comparison 
     If obj("Left").GetType.IsAssignableFrom(GetType(JValue)) Then 
      ''LHS is a string - Simple... 
      Return New SimpleComparison With { 
       .Id = Id, 
       .Left = obj("Left").ToObject(Of String)(), 
       .Right = obj("Right").ToObject(Of String)()} 
     Else 
      Return New ComplexComparison With { 
      .Id = Id, 
      .Left = ???, '' <<Problem 
      .Right = ???}'' <<Problem 
     End If 
    Else 
     Return Nothing 
    End If 
End Function 
End Class 

從產生的If的分支複雜的對象是我陷入困境的地方。如何重新調用obj("Left")obj("Right")(其類型爲JToken)上的解串器?或者我應該將它們投射到JObject,然後將這些代碼分解爲單獨的函數並遞歸調用它?

回答

2

這竟然是比我預想和JSON.Net完成所有繁重的我簡單...

Public Overrides Function ReadJson(reader As Newtonsoft.Json.JsonReader, objectType As Type, existingValue As Object, serializer As Newtonsoft.Json.JsonSerializer) As Object 
    Dim Ret As Comparison 
    Dim JComparison As JObject = JObject.Load(reader) 
    If JComparison("Left").GetType.IsAssignableFrom(GetType(JValue)) Then 
     Ret = New SimpleComparison 
    Else 
     Ret = New ComplexComparison 
    End If 
    serializer.Populate(JComparison.CreateReader(), Ret) 
    Return Ret 
End Function