Attributes and Array of Const
Attributes and Array of Const
How annoying!
type
Values = class(TCustomAttribute)
Constructor Create(const Name: String; Params: array of const);
end;
TMyClass = class
...
public
[Values('Default', [1, 2.0, 'three'])] <-- E2026
property List1: TMyVariantList;
E2026 - Constant expression expected
and what a tragic help entry :/
http://docwiki.embarcadero.com/RADStudio/XE5/en/E2026_Constant_expression_expected_(Delphi)
Question: In what way is that array not constant at compile time?
How annoying!
type
Values = class(TCustomAttribute)
Constructor Create(const Name: String; Params: array of const);
end;
TMyClass = class
...
public
[Values('Default', [1, 2.0, 'three'])] <-- E2026
property List1: TMyVariantList;
E2026 - Constant expression expected
and what a tragic help entry :/
http://docwiki.embarcadero.com/RADStudio/XE5/en/E2026_Constant_expression_expected_(Delphi)
Question: In what way is that array not constant at compile time?
Does the following work?
ReplyDeleteConstructor Create(const Name: String; const Params: array of const);
Nope. Same error, same spot.
ReplyDeleteGenerics isn't Delphi's strongest point, I just did a quick test with "TVariantArray = array of variant", but I got incompatible with set, the "TVariantArray.Create(1, 2, 'test')" doesn't work, so, I guess we're out of luck on this one... -- ran the test in D2010
ReplyDeleteNote that this is Const, not variant.
ReplyDeleteIt's perfectly legal to have a
procedure TMyClass.Create(const aList: array of const);
but it's not supported for attributes :(
Perhaps our resident Generics and RTTI guru Stefan Glienke knows of a QC, or have insights to why this is not possible?
Lars Fosdal I've noticed and am aware of difference, but I thought a hackish "array of variant" might work, apparently not... ):
ReplyDeleteReported it as http://qc.embarcadero.com/wc/qcmain.aspx?d=123972
ReplyDeleteUpdate
ReplyDeleteIt also fails for explicitly typed arrays
type
Values = class(TCustomAttribute)
Constructor Create(const Name: String; const Params: array of const);
end;
Strings = class(TCustomAttribute)
Constructor Create(const Name: String; const Params: array of String);
end;
const
SomeStrings : Array[0..2] of String = ('1', '2.0', 'three');
type
TMyClass = class
private
FList: TStringList;
public
[Strings('Default', SomeStrings)] //<-- E2026 Constant expression expected
[Strings('Default', ['1', '2.0', 'three'])] //<-- E2026 Constant expression expected
[Values('Default', [1, 2.0, 'three'])] //<-- E2026 Constant expression expected
property List: TStringList read FList;
end;
Lars Fosdal whatever, good thing we got the monkey! /:
ReplyDeleteTyped consts are not really consts, they are just variables with write protection.
ReplyDeleteJust try this:
type
MyAttribute = class(TCustomAttribute)
constructor Create(const AInteger: Integer);
end;
const
CMyInteger: Integer = 3;
type
TForm = class(TForm)
private
[My(CMyInteger)]
procedure Foo;
end;
You will get the compile error E2026.
If you just write CMyInteger = 3; everything compiles.
Fabian S. Biehn "Typed consts are not really consts, they are just variables with write protection."
ReplyDeleteunless you turn on "writable constants" flag on (:
Fabian S. Biehn - In the initial post, the constants are not typed. I guess the compiler can't handle building lists of constant references within the attribute definition, for some reason.
ReplyDeleteCan arrays even be declared not typed? I can write
ReplyDeleteconst CMyStringArray: array[0..1] of Integer = (1, 2);
but not
const CMyStringArray = (1, 2);
Are there other ways?
I think your [1, 2.0, 'three'] is also an typed array.
That [1, 2.0, 'three'] kind of array is not a const. I need to dig into it, but I think at run-time it is assembled code wise.
ReplyDeletearray of const is an open array of TVarRec. Read Rudys article about it: http://rvelthuis.de/articles/articles-openarr.html.
ReplyDeleteopen arrays cannot be const
Try array of string it doesn't work either.
It still feels illogical.
ReplyDeleteIt's an array of constant values, defined at compile time, and not possible to reference by other code.
Elsewhere in the code - they would for all practical purposes be constants.
The thing is how the compiler handles open array parameters and how arguments to the attribute constructor are stored. I am not saying it is impossible to implement but the current mechanics don't support it.
ReplyDeleteI wonder if this QC entry went the way of the Dodo...
ReplyDeleteTime to update it with a TArray example in the QP?
Ah, there is one already: quality.embarcadero.com - Log in - Embarcadero Technologies
ReplyDelete