Add new comment

Delphi attributes and ordinal (simple) types

The custom attributes don't work with ordinal (simple) type aliases in Delphi including last version XE 10.

type
  [MaxLengthAttribute(100)]
  TTestType = string;

The workaround is to define a real subtype.

type
  [MaxLengthAttribute(100)]
  TTestType = type string;

Another workaround is to define attributes directly for class properties:

TTestType = type string;
...
class TMyClass
  [MaxLengthAttribute(100)]
  property MyProp: TTestType... 
end;

Complete example:

program Project1;
 
uses
  RTTI;
 
type
  MaxLengthAttribute = class(TCustomAttribute)
  private
    FMaxLength: integer;
  public
    constructor Create(const AMaxLength: integer);
    property MaxLength: integer read FMaxLength write FMaxLength;
  end;
 
type
  [MaxLengthAttribute(100)]
  TTestType = type string;
 
constructor MaxLengthAttribute.Create(const AMaxLength: integer);
begin
  inherited Create;
  FMaxLength := AMaxLength;
end;
 
var
  LContext: TRttiContext;
  AType: TRttiType;
  Attrs: TArray<TCustomAttribute>;
  Attr: TCustomAttribute;
 
begin
  LContext := TRttiContext.Create;
  AType := LContext.GetType(TypeInfo(TTestType));
  Writeln(AType.Name);
  Attrs := AType.GetAttributes();
  for Attr in Attrs do
    Writeln(Attr.ClassName);
  LContext.Free;
end.

The real problem is that Delphi compiler accept attributes of non-existing classes. I.e. this code will compile without errors.

program Project1;
 
uses
  RTTI;
 
type
  [UndefinedAttributeClass()]
  TTestType = type string;
 
var
  s: TTestType;
begin
  s := 'UndefinedAttributeClass does not exist!';
  Writeln(s);
end.