TCustomAttribute - "预期的常量表达式"编译错误

iam*_*osy 6 delphi delphi-xe

给出以下代码段:

type
  MyIntf = interface
    ['{C6184693-663E-419F-B2DA-4DA1A0E33417}']
    procedure Foo;
  end;

  InvisiblePropInterfaces = class(TCustomAttribute)
  private
    FGUIDS: array of TGUID;
  public
    constructor Create(const GUIDS: array of TGUID);
  end;

  [InvisiblePropInterfaces([MyIntf])]  // <-- Constant expression expected error
  TMyClass = class(TInterfacedObject, MyIntf)
    procedure Foo;
  end;
Run Code Online (Sandbox Code Playgroud)

为什么编译器认为这不是一个常量表达式?但鉴于我使用像这样的InvisiblePropInterfaces,编译器很高兴?

...
var
  I: InvisiblePropInterfaces;
begin
  I:= InvisiblePropInterfaces.Create([MyIntf]);
...
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 7

属性文档的相关部分是这样的:

重要的是要理解传递给属性构造函数的值必须是常量表达式.因为这些值必须直接嵌入到生成的二进制文件中,所以无法传递需要运行时评估的表达式.这对在编译时可以传递给属性的信息提出了一些限制:

  • 只允许使用常量表达式,包括集合,字符串和序数表达式.
  • out和var参数不能使用,因为它们需要运行时评估传递参数的地址.
  • 无法使用Addr()内在函数和@运算符.
  • TypeInfo()运算符可用于传递类型信息,因为RTTI块地址在编译时是已知的.
  • 允许类引用,因为元类地址(如TypeInfo()的情况)在编译时是已知的.

关键点在于,常量表达式是一个技术Pascal术语,与常量不同.我怀疑这是混乱的根源.

由于不可能有一个可以传递给a的常量表达式,因此TGUID您的属性运气不佳.实际上,拥有一个可以传递给open数组参数的常量表达式是不可能的.

我想你可以使用它的字符串表示GUID来解决这个难题,但这会让你感到麻烦复制并且无法传递GUID数组.