Jan Doggen
Jan Doggen

Reputation: 9106

No overloaded version with these arguments - var param with read/write property

I have two overloaded procedures, of which I want to call the second one:

function  ModifySyncProperties(AEWSItemId: String; AEvent: TcxSchedulerEvent; var AEWSChangeKey: String): Boolean; overload;
function  ModifySyncProperties(AEWSItemId: String; ATTID: Integer; ASyncID: String; var AEWSChangeKey: String): Boolean; overload;

This fails with an error, though:

lSuccess := FDMExchange.ModifySyncProperties(lEWSId, lApp.EventID, lNewOutlookID, lApp.EWSItemChangeKey);

There is no overloaded version of 'ModifySyncProperties' that can be called with these arguments

This works, though:

lChangeKey := lApp.EWSItemChangeKey;
lSuccess := FDMExchange.ModifySyncProperties(lEWSId, lApp.EventID, lNewOutlookID, lChangeKey);
lApp.EWSItemChangeKey := lChangeKey;

Here are the types and variables:

lNewOutlookID,
lEWSID,
lChangeKey     : String;
lApp           : TEWSAppointment;
lSuccess       : Boolean;

TEWSAppointment is defined in the interface section of another unit as this:

TEWSAppointment = class
private
  FEventID: Integer;
  ...
  FEWSItemChangeKey: String;
  ...
public
  property EventID: Integer read FEventID write FEventID;
  ...
  property EWSItemChangeKey: String read FEWSItemChangeKey write FEWSItemChangeKey;
  ...
end;

Why does the compiler not accept the read/write lApp property as a var parameter?

I'm using Delphi Rio 10.3.1.

Upvotes: 3

Views: 575

Answers (1)

David Heffernan
David Heffernan

Reputation: 613392

The documentation for var parameters says:

If a routine's declaration specifies a var parameter, you must pass an assignable expression - that is, a variable, typed constant (in the {$J+} state), dereferenced pointer, field, or indexed variable to the routine when you call it.

A property does not meet this requirement.

Further, the documentation for properties calls this out explicitly:

Unlike fields, properties cannot be passed as var parameters, nor can the @ operator be applied to a property.


At the implementation level, the ABI, var parameters are implemented by passed the address of the variable. Since a property does not necessarily have a backing variable with an address, the compiler cannot directly obtain such a variable address.

Furthermore, if the property getter or setter perform actions beyond reading or writing to a variable, then they would need to be called.

In principle at least the language could support the usage you wish by declaring a local variable and compiling this code:

localVar := myProperty;
foo(localVar); 
myProperty := localVar;

However, the designers of the compiler did not implement this when properties were introduced to the language.

Upvotes: 7

Related Questions