Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Casting von TJSONObject (https://www.delphipraxis.net/216366-casting-von-tjsonobject.html)

t2000 17. Dez 2024 07:13

Delphi-Version: 12 Athens

Casting von TJSONObject
 
Vielleicht ne grundsätzliche Frage zur Herangehensweise.

Ich bekomme in einer Funktion einen Parameter LParam: TJSONObject
Aus diesem soll das darin enthaltene Feld 'JSONData', welches auch wieder ein JSON-Object ist, herausgeholt werden.

Alles nicht schwer. Hier geht es um das Casting.
Habe den Code seit bestimmt 3 Jahren gehabt und jetzt erst das Problem bemerkt. (Ich kann nicht mit Sicherheit sagen, warum erst jetzt. Aber ich habe den Einsatzzweck ein wenig verändert)

Es soll also eine Kopie der JSON Daten in das Feld FJSONData kopiert werden.
Delphi-Quellcode:
var
  LParam: TJSONObject;
  LVal: TJSONValue;
begin

    LVal := LParam.GetValue( 'JSONData');
    if LVal.Null then
      FJSONData := nil
    else
      //FJSONData := TJSONObject( LVal).Clone as TJSONObject;   // hat sehr lange funktioniert. Ja eine möglich Exception war beabsichtigt.
      FJSONData := TJSONObject( TJSONObject( LVal).Clone);
Ich vermute, da LVal ein TJSONValue ist (da ja auch .Clone ein TJSONValue liefert) macht mir das casten mit "as" die Exception. (Die enthaltenen Daten sind ein korrektes JSON Objekt)
Wenn ich nun mit TJSONObject() caste, entfällt die überprüfung und es gibt keine Exception.

Ist meine Vermutung richtig oder sollte das casten mit "as" auch funktionieren?
Was ist vorgefallen, dass dieser Fehler erst nach ca. 3 Jahren auftritt?

Ich habe sehr viele Stellen in meinem Code, bei denen ich "as" nutze (anstelle von TType()) Falls dort ein falscer Typ kommt, ist die Exception sinnvoll. Aber bei TJSONValue : TJSONObject den Fehler zu melden wäre fatal.

Meinungen?

VG

t2000 17. Dez 2024 09:06

AW: Casting von TJSONObject
 
Man muss über Probleme schreiben und/oder reden. Dann kommt man selber drauf.

Das Casting ist völlig in Ordnung. In diesem Fall egal welche Variante.

Mein Fehler war, dass ich zwar auf Vorhandensein des JSON-Namen getestet hatte, aber nicht ob JSON-Value auch <> nil ist. Und das war hier der Fall.

Ein Casting TJSONObject(nil) funktioniert.
Ein Casting nil as TJSONObject aber nicht.

Ich könnte jetzt den ganzen Beitrag löschen, aber vielleicht hilft er ja irgendwann irgendjemanden weiter.

Rollo62 17. Dez 2024 09:16

AW: Casting von TJSONObject
 
Vielleicht hat sich die Struktur oder der Inhalt der JSON-Daten geändert. Es könnte sein, dass LVal.Clone an dieser Stelle nicht mehr immer ein TJSONObject ist.

Du könntest möglicherweise LVal.Clone.ClassName prüfen, wenn der Fehler auftritt.

Zur Abfrage könnte man den Typ vorab mit "is" testen, was aber dann zweimal Clone aufruft, und das ist auch nicht so super.

Edit: Ich sehe, Du hast schon selbst geantwortet, schicke ich aber trotzdem noch ab ...

Das hier sollte aber OK sein
Delphi-Quellcode:
LVal := LParam.GetValue('JSONData');

if Assigned(LVal) and not LVal.Null then
begin
  // Sichere Zuweisung mit Clone
  FJSONData := TJSONObject(LVal.Clone) as TJSONObject;
end
else
  FJSONData := nil;


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz