Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do Delphi Attributes require a constant parameter? If so, why?

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?

like image 395
Nick Hodges Avatar asked May 10 '11 16:05

Nick Hodges


1 Answers

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.

like image 52
Mason Wheeler Avatar answered Sep 18 '22 12:09

Mason Wheeler