扩展Newtonsoft.Json.Linq.JObject类

时间:2017-03-15 01:10:56

标签: vb.net inheritance json.net extending

我想扩展Newtonsoft.Json.Linq.JObject类,以便获得对JObject内容即时生成的某些表达式的快速访问(以属性的形式)。让我们调用扩展类JRecord

我还需要JObject个实例可以轻松地转换为扩展类型JRecord。问题是:我如何采用JObject实例并将其转换为我的扩展类型(也继承自JObject),以某种方式保留其所有内容但使用额外属性“修饰”当从JObject扩展回JRecord时,从JRecord缩小到JObject并将这些属性“条带化”?

下面是我的第一个划痕,我省略了大部分属性,因为它的字符串构建很复杂且与问题无关,这会引发自定义CType()运算符,其中.NET告诉我

  1. Conversion operators cannot convert from a type to its base type

  2. Conversion operators cannot convert from a base type

  3. 那么,我该怎么办?我应该创建一个简单的新实例并创建与我想要投射的对象具有相同内容的子项吗?谢谢你的帮助!

    Public Class JRecord
        Inherits JObject
    
        Public Sub New()
            MyClass.New
        End Sub
    
        Public ReadOnly Property Id As Integer
            Get
                Return MyBase.Value(Of Integer)("id")
            End Get
        End Property
    
        Public ReadOnly Property NomeSigla As String
            Get
                Return String.Format(
                    "{0} ({1})", 
                    MyBase.Value(Of String)("nome"), 
                    MyBase.Value(Of String)("sigla"))
            End Get
        End Property
    
        Public Overloads Shared Narrowing Operator CType(json_object As JObject) As JRecord
            Return DirectCast(json_object, JRecord)
        End Operator
    
        Public Overloads Shared Widening Operator CType(json_record As JRecord) As JObject
            Return json_record
        End Operator
    
    End Class
    

1 个答案:

答案 0 :(得分:1)

在这种情况下,我不会使用继承和转换运算符。相反,我会在这里使用作文。换句话说,让JRecord类包装原始JObject并根据需要委托给它。要从JObject转换为JRecord,请使JRecord的构造函数接受JObject。换句话说,只需在JObject上设置一个JRecord属性,然后让它直接返回内部JObject

Public Class JRecord

    Private innerJObject As JObject

    Public Sub New(jObject As JObject)
        innerJObject = jObject
    End Sub

    Public ReadOnly Property JObject As JObject
        Get
            Return innerJObject
        End Get
    End Property

    Public ReadOnly Property Id As Integer
        Get
            Return innerJObject.Value(Of Integer)("id")
        End Get
    End Property

    Public ReadOnly Property NomeSigla As String
        Get
            Return String.Format(
                "{0} ({1})",
                innerJObject.Value(Of String)("nome"),
                innerJObject.Value(Of String)("sigla"))
        End Get
    End Property

End Class

然后你可以这样做:

Dim jr as JRecord = new JRecord(JObject.Parse(jsonString))
Dim id as Integer = jr.Id
Dim ns as String = jr.NomeSigla
Dim jo as JObject = jr.JObject
...

如果您绝对必须使用继承,因为您希望将JRecord直接传递到应用程序中只需要JObject的其他位置,您可以这样做:

Public Class JRecord
    Inherits JObject

    Public Sub New(jObject As JObject)
        MyBase.New(jObject)
    End Sub

    Public ReadOnly Property JObject As JObject
        Get
            Return Me
        End Get
    End Property

    Public ReadOnly Property Id As Integer
        Get
            Return Value(Of Integer)("id")
        End Get
    End Property

    Public ReadOnly Property NomeSigla As String
        Get
            Return String.Format(
                "{0} ({1})",
                Value(Of String)("nome"),
                Value(Of String)("sigla"))
        End Get
    End Property

End Class

这几乎是一回事,除了现在JRecord 一个JObject所以你可以自由传递它。权衡是现在它必须在首次构造JRecord时复制所有属性。我们利用JObject的内置复制构造函数来完成此任务。