【问题标题】:TCustomAttribute - "Constant expression expected" compile errorTCustomAttribute - “预期的常量表达式”编译错误
【发布时间】:2012-01-23 17:46:42
【问题描述】:

给定以下代码sn-p:

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]);
...

【问题讨论】:

    标签: delphi delphi-xe


    【解决方案1】:

    attributes documentation 的相关部分是这样的:

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

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

    关键是constant expression 是一个技术帕斯卡术语,它与常数不同。我怀疑这是混乱的根源。

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

    我想你可以使用GUID 的字符串表示来解决这个难题,但这会给你留下混乱的重复并且无法传递 GUID 数组。

    【讨论】:

    • 我第一次真正使用属性似乎不太走运。那么,我必须改变我的设计,用另一个接口来装饰我的类,比如:IInvisiblePropInterfaces = interface function GetGuids: array of TGuid
    【解决方案2】:

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

    【讨论】:

    • 不是真的。您可以毫无问题地调用 InvisiblePropInterfaces.Create([MyIntf]) 。似乎在它的属性上下文中它没有编译。
    • 手动调用时,不必再是常量表达式了。
    • @Rob,但是 ([MyIntf]) 不是常量表达式吗?
    • 不,([MyIntf]) 不是常量表达式。那是因为MyIntf 不是一个常量表达式。它是一个记录常量,类型化的常量不是真正的常量。当编译器想要一个常量表达式时,它需要一个 true 常量。
    • 几乎,@David。可以有浮点真常量,但文档显然需要序数。否则,看起来真正的常量是常量表达式的子集。我不认为真正的常量中允许使用类引用或类型信息——通常,任何涉及获取单例地址的东西。另一方面,我从未尝试过。
    猜你喜欢
    • 1970-01-01
    • 2016-06-19
    • 1970-01-01
    • 2022-11-15
    • 1970-01-01
    • 2016-06-19
    • 2017-07-24
    • 1970-01-01
    • 2011-01-03
    相关资源
    最近更新 更多