Delphi D10 Seattle中的内联表达式解析器无法在某些条件下评估表达式

时间:2017-07-26 12:31:04

标签: delphi expression anonymous-function overloading

我有一个对象,唯一的责任就是保持价值。这个值可以直接通过构造函数传递,或者构造函数可以使用匿名函数告诉对象如何获取值。

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;

该匿名函数将仅在第一次需要该值时执行,然后该值将被缓存以在进一步调用中返回。 除了一种情况外,这种情况正如预期的那样起作用,如下所述:

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;

此代码将按预期完美地运行。 由于FCoordinate本身是IValue,FCoordinate.Value将返回Double原语。因此,当与D10的本地记录助手结合使用时,FCoordinate.Value.ToString将返回s将保留的原始字符串。 然后,TValue<string>.New的一个重载将接受一个原始字符串值,s就在那个小巷里。 一切都很好。

但是,s变量是或应该是可选的。它只会被使用一次,所以我们可以(应该)用表达式本身替换它。

但是当我这样做时:

function TGeoCoordinate.ToStringValue: IValue<string>;
begin
  Result := TValue<string>.New(FCoordinate.Value.ToString);
end;

编译器将返回[dcc32 Error] E2250 There is no overloaded version of 'New' that can be called with these arguments

在尝试检测问题时,我注意到这也可以正常工作:

function TGeoCoordinate.ToStringValue: IValue<string>;
begin
  Result := TValue<string>.New((FCoordinate.Value.ToString));
end;

在表达式中添加额外的一对parentesis将强制它评估完整表达式FCoordinate.Value.ToString,并且TValue.New将不再失败。

尽管如此,我确实认为这不是必要的。

然后我尝试创建另一个IValue实现,其中类函数New没有重载,只接受T值,这也可以正常工作,这意味着编译器被重载版本{{1接受匿名函数。

这可能是编译器错误,还是我错过了这张图片中的内容?

我试图搜索类似的问题,但是对于任何可以过滤它的搜索字词都没有问题,因为这个问题使用了相当普遍的措辞。

0 个答案:

没有答案