Consider the following (uncompilable) code:
program AttributesTestProgram;
{$APPTYPE CONSOLE}
uses
SysUtils,
Classes,
RTTI;
type
TDisplayTextAttribute = class(TCustomAttribute)
private
FDisplayText: string;
public
constructor Create(aDisplayText: string);
property DisplayText: string read FDisplayText write FDisplayText;
end;
constructor TDisplayTextAttribute.Create(aDisplayText: string);
begin
FDisplayText := aDisplayText;
end;
function GetFirstName: string;
begin
Result := 'First Name';
end;
type
TCustomer = Class(TObject)
private
FFirstName: string;
FLastName: string;
FStreetAddress: string;
FZIP: string;
FState: string;
FCity: string;
FPhone: string;
published
[TDisplayTextAttribute(GetFirstName)]
property FirstName: string read FFirstName write FFirstName;
end;
begin
// Code that does the work removed for clarity....
Readln;
end.
I wonder, naturally, why this fails to compile with the error:
[DCC Error] AttributesTestProgram.dpr(40): E2026 Constant expression expected
I assume that it has something to do with the idea that attributes have to be bound at compiler time, or something along those lines.
Hence, my questions is this:
Is there any way to "beat the system" here and get a runtime value into that spot in the attribute?
Yeah, you need constants because the parameters are evaluated to constants at compile time and stored in the RTTI tables. Also, attributes belong to the class, not to object instances, so if you have more than one TCustomer, your idea becomes nonsensical.
You can beat the system by giving the attribute a parameterless constructor (or no constructor at all) and changing the DisplayText property to a method on it that accepts either a string or an object from which you can extract a string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With