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:
You cannot pass method references/pointers as attribute parameters in Delphi — the compiler requires constant expressions.
The workaround is to pass the method name as a string ('MethodIWantToReferToInAnAttribute').
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.