Какие языковые элементы могут быть аннотированы с использованием атрибутов языка Delphi?

29

В Delphi 2010 появились пользовательские атрибуты, которые можно добавить к объявлениям типов и методам. Для каких элементов языка может использоваться пользовательский атрибут?

Примеры, которые я нашел до сих пор, включают объявления классов, поля и методы. (И общие классы AFAIK не поддерживают пользовательские атрибуты).

Некоторые примеры показаны в в этой статье. Похоже, что переменные (внешние по отношению к любому объявлению класса) также могут иметь атрибуты.

На основе этой статьи атрибуты могут использоваться для

  • класс и поля и методы записи
  • параметры метода
  • Свойства
  • нелокальные объявления перечисления
  • объявления не локальных переменных

Существуют ли другие элементы языка, где могут быть размещены атрибуты?


Обновление: в этой статье указывается, что пользовательские атрибуты могут быть помещены перед свойствами: http://francois-piette.blogspot.de/2013/01/using-custom-attribute-for-data.html

Он содержит этот пример кода:

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;

Я предполагаю, что есть также способ читать атрибуты в аргументах метода, например

procedure Request([FormParam] AUsername: string; [FormParam] APassword: string);
  • 2
    +1 интересный вопрос. В документации говорится, что атрибуты предназначены для «аннотирования типов и членов типов» - я подозреваю, что это означает что-либо в предложении type , а также все, что объявлено внутри записи или класса (переменные-члены, свойства, функции, процедуры, внутренние классы и т. Д.). .)
  • 0
    Эта ссылка о свойствах не работает для меня. Если вы помните, что он сказал, не могли бы вы отредактировать ответ ниже, чтобы продемонстрировать использование атрибутов в свойствах? (Я не могу найти другой источник для этой ссылки, потому что цитата не содержит ничего об авторе, теме, форуме или даже дате.)
Показать ещё 1 комментарий
Теги:
annotations
delphi-xe2
delphi-2010
delphi-xe

1 ответ

23
Лучший ответ

Интересный вопрос! Вы можете объявлять атрибуты на почти ничего, проблема заключается в получении их с помощью RTTI. Здесь приведена демонстрация быстрой консоли объявления пользовательских атрибутов для:

  • Перечисления
  • Тип функции
  • Тип процедуры
  • Тип метода (of object)
  • Тип с псевдонимом
  • Тип записи
  • Тип класса
  • Тип записи, который является внутренним для класса
  • Поле записи
  • Способ записи
  • Поле экземпляра класса
  • Поле класса class (class var)
  • Метод класса
  • Глобальная переменная
  • Глобальная функция
  • Локальная переменная

Не нашел способ объявить пользовательский атрибут для property класса. Но настраиваемый атрибут может быть привязан к методам getter или setter.

Код, история продолжается после кода:

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.

Проблема заключается в получении этих настраиваемых атрибутов. Если посмотреть на блок rtti.pas, пользовательские атрибуты могут быть получены для:

  • Тип записи (TRttiRecordType)
  • Тип экземпляра (TRttiInstanceType)
  • Тип метода (TRttiMethodType)
  • Тип указателя (TRttiPointerType) - что используется для?
  • Тип процедуры (TRttiProcedureType)

Невозможно получить какой-либо RTTI для уровня "unit" или локальных переменных и процедур, следовательно, нет способа получить информацию об атрибутах.

  • 2
    Отсутствие поддержки атрибутов в свойствах является странным (и позор - свойства - одна из замечательных вещей в классах Delphi.) Кстати, +1 за отличный ответ.
  • 2
    @ Дэвид М: посмотрите мое обновление, похоже, атрибуты свойств работают нормально
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню