Search code examples
delphi

Why can't TryGetValue modify a function parameter's property even it's marked as var or out?


I've faced this and even found some answers about the same issue on C# but nothing delphi related:

function BuildOrderFromJSON(const AObj: TJSONObject; var AOrd: TAnyPedido): Boolean;
begin
  AOrd := TAnyPedido.Create;
  AObj.TryGetValue('id', AOrd.id);
end;

This code raises an error on the AObj.TryGetValue('id', AOrd.id); saying there's no overloaded version of TryGetValue that can be called with these arguments. The same error happens if AOrd is received as out parameter:

function BuildOrderFromJSON(const AObj: TJSONObject; out AOrd: TAnyPedido): Boolean;
begin
  AOrd := TAnyPedido.Create;
  AObj.TryGetValue('id', AOrd.id);
end;

Given the AOrd.id is a property of Integer type I tested the following

function BuildOrderFromJSON(const AObj: TJSONObject; var AOrd: TAnyPedido): Boolean;
var
  temp: Integer;
begin
  AOrd := TAnyPedido.Create;
  AObj.TryGetValue('id', temp);
end;

And surprisingly (for me, atleast), it works. I wonder if it's something related to how properties are interpreted by the compiler or something, it's not a deal breaker but got me curious, why does it happen?


Solution

  • A PROPERTY is not a variable - it might be implemented as a Getter/Setter (Read and Write methods) and not have any memory backing at all.

    A VAR or OUT parameter needs a pointer to (address of) a memory location where the value is stored, but as I said above, there's no guarantee that a PROPERTY has a backing field, nor that it is of the appropriate type (it could be that the PROPERTY is of type STRING and the backing field is of type INTEGER, and the conversion between the two are done in the Getter/Setter), so a PROPERTY is not compatible with a VAR/OUT parameter.