Attributes and references to methods

Howdy,

Trying to be a bit creative with Delphi 10.1 Berlin, and would like to do something like this:

type
  TExecuteMethod = procedure of object;

type
  MyAttribAtttribute = class(TCustomAttribute)
  public
    constructor Create(const AMethod: TProc (* Pointer *) (* TExecuteMethod *));
  end;

type
  TMyClass = class
  protected
    (* class *) procedure MethodIWantToReferToInAnAttribute;
  public
    [MyAttrib(MethodIWantToReferToInAnAttribute)]
    //[MyAttrib(@MethodIWantToReferToInAnAttribute)]
    //[MyAttrib(TMyClass.MethodIWantToReferToInAnAttribute)]
    procedure SomeOtherMethod;
  end;
```  

I have tried a number of ways without success, mainly with E2026 Constant expression expected.

Without resorting to using strings (and RTTI), can I directly refer to a method in an Attribute?

Claude via SmartCodeInsight doesn’t give much hope …

Unfortunately, you cannot pass a method reference, method pointer, or procedure pointer as an attribute parameter in Delphi. Attribute constructor parameters are limited to constant expressions (ordinal types, strings, floating-point, class references, etc.).

The common workaround is to pass the method name as a string and then use RTTI to look it up at runtime.

Key points:

  1. You cannot pass method references/pointers as attribute parameters in Delphi — the compiler requires constant expressions.
  2. The workaround is to pass the method name as a string ('MethodIWantToReferToInAnAttribute').
  3. At runtime, you use RTTI (TRttiContext, TRttiType.GetMethod) to find the attribute on SomeOtherMethod, read the stored method name, look up that method, and invoke it.

This is the standard Delphi pattern for referencing methods in attributes.

Wait. I think I’m missing something (I once had more of a clue about attributes, but that stuff has left my head atm)

13.1 compiles this … gives 3 warnings about ‘unknown custom attribute’.

I started the file to see if something could be done with eg a record static class procedure.

program Project2;
{$APPTYPE CONSOLE}

uses System.SysUtils;
type
  TExecuteMethod = procedure of object;
type
  MyAttribAtttribute = class(TCustomAttribute)
  public
    constructor Create(const AMethod: TProc); //TExecuteMethod );
  end;

  constructor MyAttribAtttribute.Create(const AMethod: TProc); // TExecuteMethod);
  begin
  end;

type
  TMyClass = class
  protected
    (* class *) procedure MethodIWantToReferToInAnAttribute;
  public
    [MyAttrib(MethodIWantToReferToInAnAttribute)]
    [MyAttrib(@MethodIWantToReferToInAnAttribute)]
    [MyAttrib(TMyClass.MethodIWantToReferToInAnAttribute)]
    procedure SomeOtherMethod;
  end;

  procedure TMyClass.MethodIWantToReferToInAnAttribute; begin end;
  procedure TMyClass.SomeOtherMethod; begin end;

begin

end.

That is because I did a typo and had three ts in Atttribute. It should be MyAttribAttribute with only two ts in Attribute.

That is what you get when you write it out by hand - apologies.

You have passed the “Nick is not an AI” test. :joy:

Are you sure? It would be the typical type of “mistake” AI would do (at least from my experience).