¿Qué elementos de idioma se pueden anotar usando la función de idioma de atributos de Delphi?


Delphi 2010 introdujo atributos personalizados que se pueden agregar a declaraciones de tipos y métodos. ¿Para qué elementos de lenguaje se puede utilizar un atributo personalizado?

Los ejemplos que he encontrado hasta ahora incluyen declaraciones de clase, campos y métodos. (Y las clases genéricas de AFAIK no admiten atributos personalizados).

Algunos ejemplos se muestran en este artículo. Parece que las variables (externas a cualquier declaración de clase) también pueden tener atributos.

Basado en esto artículo, los atributos se pueden utilizar para

  • campos y métodos de clase y registro
  • parámetros del método
  • propiedades
  • declaraciones de enumeración no locales
  • declaraciones de variables no locales

¿Hay otros elementos del lenguaje donde los atributos se pueden colocar?


Actualización: este artículo indica que los atributos personalizados se pueden colocar antes de las propiedades: http://francois-piette.blogspot.de/2013/01/using-custom-attribute-for-data.html

Contiene este ejemplo de código:

type
  TConfig = class(TComponent)
  public
    [PersistAs('Config', 'Version', '1.0')]
    Version : String;
    [PersistAs('Config', 'Description', 'No description')]
    Description : String;
    FTest : Integer;
    // No attribute => not persistent
    Count : Integer;
    [PersistAs('Config', 'Test', '0')]
    property Test : Integer read FTest write FTest;
  end;

Supongo que también hay una forma de leer atributos en argumentos de método como

procedure Request([FormParam] AUsername: string; [FormParam] APassword: string);
Author: mjn, 2011-05-25

1 answers

Pregunta Interesante! Puede declarar atributos en casi cualquier cosa, el problema es recuperarlos usando RTTI. Aquí hay una demostración rápida de la consola de declarar atributos personalizados para:

  • Enums
  • Tipo de función
  • Tipo de procedimiento
  • Tipo de método (of object)
  • Tipo alias
  • Tipo de registro
  • Clase tipo
  • Tipo de registro interno de una clase
  • Campo de registro
  • Método de registro
  • Clase campo de instancia
  • Campo Class class(class var)
  • Método de clase
  • Variable global
  • Función global
  • Variable local

No encontró una manera de declarar un atributo personalizado para un property de una clase. Pero un atributo personalizado se puede adjuntar a los métodos getter o setter.

Código, la historia continúa después del código:

program Project25;

{$APPTYPE CONSOLE}

uses
  Rtti;

type
  TestAttribute = class(TCustomAttribute);

  [TestAttribute] TEnum = (first, second, third);
  [TestAttribute] TFunc = function: Integer;
  [TestAttribute] TEvent = procedure of object;
  [TestAttribute] AliasInteger = Integer;

  [TestAttribute] ARecord = record
    x:Integer;
    [TestAttribute] RecordField: Integer;
    [TestAttribute] procedure DummyProc;
  end;

  [TestAttribute] AClass = class
  strict private
    type [TestAttribute] InnerType = record y:Integer; end;
  private
    [TestAttribute]
    function GetTest: Integer;
  public
    [TestAttribute] x: Integer;
    [TestAttribute] class var z: Integer;
    // Can't find a way to declare attribute for property!
    property Test:Integer read GetTest;
    [TestAttribute] class function ClassFuncTest:Integer;
  end;

var [TestAttribute] GlobalVar: Integer;

[TestAttribute]
procedure GlobalFunction;
var [TestAttribute] LocalVar: Integer;
begin
end;

{ ARecord }

procedure ARecord.DummyProc;
begin
end;

{ AClass }

class function AClass.ClassFuncTest: Integer;
begin
end;

function AClass.GetTest: Integer;
begin
end;

begin
end.

El problema es recuperar esos atributos personalizados. Mirando la unidad rtti.pas, los atributos personalizados pueden para:

  • Tipo de registro (TRttiRecordType)
  • Tipo de instancia(TRttiInstanceType)
  • Tipo de método (TRttiMethodType)
  • Tipo de puntero (TRttiPointerType) - ¿para qué se usa?
  • Tipo de procedimiento (TRttiProcedureType)

No hay forma de recuperar ningún tipo de RTTI para el nivel de "unidad" o variables y procedimientos locales, por lo tanto, no hay forma de recuperar información sobre atributos.

 25
Author: Cosmin Prund,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-09 07:11:40