skip to Main Content

I am migrating some projects from Delphi 10.4 to Delphi 11.3.
I am facing some problems with the JSON library:

See the following codes:

First case:

function TestCreate;
var
  LValue: Variant;
  LJSON: TJSONNumber;
begin
  LValue := 100;
  LJSON := TJSONNumber.Create(LValue);
end;

Compiling this, it results in:

  [dcc64 Error] _Unit.pas(74): E2251 Ambiguous overloaded call to 'Create'
  System.JSON.pas(435): Related method: constructor TJSONNumber.Create(const string);
  System.JSON.pas(439): Related method: constructor TJSONNumber.Create(const Double);

Second case:

function TestAddPair;
var
  LValue: Variant;
  LJSON: TJSONObject;
begin
  LValue := 100;
  LJSON := TJSONObject.Create();
  LJSON.AddPair('Test', LValue);
end;

Compiling this, it results in:

  [dcc64 Error] _Unit.pas(77): E2251 Ambiguous overloaded call to 'AddPair'
  System.JSON.pas(661): Related method: function TJSONObject.AddPair(const string; const Boolean): TJSONObject;
  System.JSON.pas(651): Related method: function TJSONObject.AddPair(const string; const Double): TJSONObject;
  System.JSON.pas(636): Related method: function TJSONObject.AddPair(const string; const string): TJSONObject;

Both used to work properly on Delphi 10.4, but on Delphi 11.3 they do not compile.
Is there a way to let them compile? I’d prefer not to modify each command that uses a Variant to create/add a JSON.

2

Answers


  1. A Variant can implicitly convert to both string or Double type without any preference for one of them.

    In R104 the constructor taking a string parameter is protected, while in 11.3 it is public.

    As Toon mentioned, you may not be able to avoid changing all the calls.

    Update: Alternatively you can create class helpers for TJSONNumber and TJSONObject with overrides for Variant. F.i. like this:

    type
      TJSONNumberHelper = class helper for TJSONNumber
      public
        constructor Create(const AValue: Variant); overload;
      end;
    
    constructor TJsonNumberHelper.Create(const AValue: Variant);
    begin
      inherited Create(Double(AValue));
    end;
    
    Login or Signup to reply.
  2. Another alternative and different approach could be using mORMot, furthermore it’s very optimized to use as little memory and very fast JSON serialization / un-serialization.

    program Project1;
    
    {$APPTYPE CONSOLE}
    
    uses
      Syncommons;
    
    var
      DoubleNumber : Double;
      VariantNumber : Variant;
      Json : variant;
    begin
      DoubleNumber := 100;
      VariantNumber := 101;
      Json := _Obj(['Double' , DoubleNumber ,
                    'Variant' , VariantNumber
                   ]);
      assert(VariantSaveJson(Json)='{"Double":100,"Variant":101}');
    end.
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search