В 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);
Интересный вопрос! Вы можете объявлять атрибуты на почти ничего, проблема заключается в получении их с помощью 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" или локальных переменных и процедур, следовательно, нет способа получить информацию об атрибутах.
type
, а также все, что объявлено внутри записи или класса (переменные-члены, свойства, функции, процедуры, внутренние классы и т. Д.). .)