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

时间:2012-01-23 17:46:43

标签: 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;

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

...
var
  I: InvisiblePropInterfaces;
begin
  I:= InvisiblePropInterfaces.Create([MyIntf]);
...

2 个答案:

答案 0 :(得分:7)

attributes documentation的相关部分是:

  

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

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

关键是constant expression是一个技术Pascal术语,与常量不同。我怀疑这是混乱的根源。

由于无法将一个常量表达式传递给TGUID,因此您的属性不通。实际上,有一个可以传递给开放数组参数的常量表达式是不可能的。

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

答案 1 :(得分:1)

这是一个已知的限制。 TGUID被声明为记录类型,无法创建记录常量表达式。