2017-03-15 4 views
0

Ich möchte Newtonsoft.Json.Linq.JObject Class erweitern, um einen schnellen Zugriff (in Form von Eigenschaften) auf einige Ausdrücke zu erhalten, die von JObjects Inhalt on-the-fly gemacht werden. Lassen Sie uns die erweiterte Klasse JRecord aufrufen.Erweitern Newtonsoft.Json.Linq.JObject Klasse

Ich brauche auch, dass JObject Instanzen können leicht zu und von der erweiterten Art JRecord umgewandelt werden. Die Frage ist: Wie nehme ich eine JObject Instanz und wirf sie als meinen erweiterten Typ (der auch von JObject erbt), so dass sie ihren gesamten Inhalt behält, aber mit den zusätzlichen Eigenschaften "angezogen" wird, wenn sie von JObject bis JRecord und " Gestreifte "dieser Eigenschaften beim Erweitern von JRecord zurück zu JObject?

Unten ist mein erster Grund auf neu und ich die meisten Eigenschaften weggelassen, weil seine String-Gebäude für das Problem komplex und irrelevant ist, die auf beiden benutzerdefinierten CType() Betreiber erhebt, wo .NET mir sagt, dass

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

  2. Conversion operators cannot convert from a base type

Also, was soll ich tun? Soll ich eine nackte neue Instanz erstellen und untergeordnete Objekte mit denen des Objekts erstellen, das ich umwandeln möchte? Danke für jede Hilfe!

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 

Antwort

1

Ich würde in diesem Fall nicht Vererbungs- und Konvertierungsoperatoren verwenden. Stattdessen würde ich hier Komposition verwenden. Mit anderen Worten, machen Sie die JRecord Klasse wickeln Sie das Original JObject und delegieren Sie es bei Bedarf. Um von einem JObject zu einem JRecord zu konvertieren, lassen Sie den Konstruktor des JRecord einen JObject akzeptieren. Um den anderen Weg zu gehen, machen Sie einfach eine JObject Eigenschaft auf JRecord und lassen Sie die innere JObject direkt zurückgeben.

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 

Dann können Sie Dinge tun, wie folgt:

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 
... 

Wenn Sie unbedingt Vererbung verwenden müssen, weil Sie die JRecord direkt an anderen Orten in der Anwendung zu übergeben wollen, dass nur ein JObject erwarten Sie Dazu könnte:

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 

Dies ist fast das gleiche, außer jetzt die JRecordist ein JObject so können Sie es frei herumreichen. Der Kompromiss besteht darin, dass jetzt alle Eigenschaften kopiert werden müssen, wenn der JRecord zum ersten Mal erstellt wird. Wir nutzen dazu den integrierten Kopierkonstruktor JObject.

+0

Ja, als ich weiter recherchierte, fand ich heraus, dass dies der * richtige * Weg ist, hier zu arbeiten. Aber angenommen, ich habe diese Klasse, die 'JObject' in mehreren Operationen zurückgibt und jetzt' JRecord' zurückgibt. Wie könnte ich den neuen Typ nahtlos "JObject" entlang des Rests der Anwendung nachahmen, oder dies ist nicht möglich und ich strebe zu viel? (Ich weiß, dass ich das Ganze besser umgestalten sollte, und ich beabsichtige, es zu tun, aber ich würde es gerne dazwischen laufen lassen, auch wenn es ein wenig langsamer und schwerer als vorher ist). – VBobCat

+1

Für die Orte, an denen Sie ein JObject benötigen, würde ich nur die Anrufer ändern, um 'jRecord' zu übergeben.JObject' anstatt 'jRecord' zu übergeben. Aber wenn es zu viele solche Orte zu ändern gibt, dann können Sie immer noch einen vererbungsbasierten Ansatz verwenden. Ich habe meine Antwort aktualisiert, um zu zeigen, wie. –

+0

Perfekt! Ich danke dir sehr! – VBobCat

Verwandte Themen