给出以下代码段:
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)
属性文档的相关部分是这样的:
重要的是要理解传递给属性构造函数的值必须是常量表达式.因为这些值必须直接嵌入到生成的二进制文件中,所以无法传递需要运行时评估的表达式.这对在编译时可以传递给属性的信息提出了一些限制:
- 只允许使用常量表达式,包括集合,字符串和序数表达式.
- out和var参数不能使用,因为它们需要运行时评估传递参数的地址.
- 无法使用Addr()内在函数和@运算符.
- TypeInfo()运算符可用于传递类型信息,因为RTTI块地址在编译时是已知的.
- 允许类引用,因为元类地址(如TypeInfo()的情况)在编译时是已知的.
关键点在于,常量表达式是一个技术Pascal术语,与常量不同.我怀疑这是混乱的根源.
由于不可能有一个可以传递给a的常量表达式,因此TGUID您的属性运气不佳.实际上,拥有一个可以传递给open数组参数的常量表达式是不可能的.
我想你可以使用它的字符串表示GUID来解决这个难题,但这会让你感到麻烦复制并且无法传递GUID数组.
| 归档时间: |
|
| 查看次数: |
1577 次 |
| 最近记录: |