Delphi D10 Seattle's built-in expression parser unable to evaluate an expression under certain conditions
I have an object that is only responsible for storing a value. This value can be passed directly through the constructor, or the constructor can use an anonymous function that tells the object how to get the value.
type
TDefineCached<T> = Reference to function: T;
TValue<T> = class(TInterfacedObject, IValue<T>)
private
FValue: T;
FActive: Boolean;
FDefine: TDefineCached<T>;
procedure DoDefine;
public
constructor Create(const Define: TDefineCached<T>);
class function New(const Define: TDefineCached<T>): IValue<T>; overload;
class function New(const Value: T): IValue<T>; overload;
function Value: T;
end;
This anonymous function will only be executed the first time a value is needed, and this value will then be cached to be returned on subsequent calls. This works as expected in all but one case described below:
private
FCoordinate: IValue<Double>;
// some other code
function TGeoCoordinate.ToStringValue: IValue<string>;
var
s: string;
begin
s := FCoordinate.Value.ToString;
Result := TValue<string>.New(s);
end;
This code will work fine as expected. Since FCoordinate is itself an IValue, FCoordinate.Value
returns a double primitive. Therefore, when used in conjunction with the built-in D10 write helper for Double, it FCoordinate.Value.ToString
will return a primitive string to be held s
. Then one of the overloads TValue<string>.New
will take a primitive string value, and s
- right in that alley. All perfectly.
But that variable s
is or should be optional. It will only be used once, so we could (should) replace it with the expression itself.
But when I do this:
function TGeoCoordinate.ToStringValue: IValue<string>;
begin
Result := TValue<string>.New(FCoordinate.Value.ToString);
end;
The compiler will return [dcc32 Error] E2250 There is no overloaded version of 'New' that can be called with these arguments
.
When trying to spot the problem, I noticed that this would work perfectly:
function TGeoCoordinate.ToStringValue: IValue<string>;
begin
Result := TValue<string>.New((FCoordinate.Value.ToString));
end;
Adding an extra pair of parent expressions to the expression will force it to evaluate the full expression FCoordinate.Value.ToString
and TValue.New will no longer fail.
However, I believe this is not necessary.
Then I tried to create another implementation of IValue where the function of the New class is not overloaded and only accepts the value of T, and this also works great, which means that somewhere the compiler is fooled by an overloaded version New
that accepts an anonymous function.
Could this be a compiler error or am I missing something in this snapshot?
I tried to find similar problems, but couldn't work out any search terms that might filter it enough, as this problem uses a fairly general wording.
source to share
No one has answered this question yet
See similar questions:
or similar: