(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Использование атрибутов и наследников TCustomAttribute в Delphi 2010

Источник: delphi2010
Александр Божко

В Delphi 2010 атрибуты были добавлены как функциональность языка. Они были доступны в Delphi Prism (для .Net) и вот теперь схожая функциональность появилась и для Win32.
Атрибуты являются способом закрепления метаданных за отдельно взятым типом или членом этого типа.
Они могут применяться во многих областях, и следующий код демонстрирует несколько вариантов использования атрибутов.

  // Объявление атрибута
  TAttrTest = class(TCustomAttribute)
  end;

  // Место, где вы можете использовать атрибуты
  [TAttrTest]
  TRec = Record
    [TAttrTest]
    value : String;
    [TAttrTest]
    procedure DoThis([TAttrTest]arg1: String);
  End;

  [TAttrTest]
  TMyEnum = (enOne,enTwo,enThree);

  [TAttrTest]
  TMySet = set of TMyEnum;

  [TAttrTest]
  TObj = class(TObject)
  private
    [TAttrTest]
    FID: Integer;
  public
    [TAttrTest]
    FName : String;
    [TAttrTest]
    property Id : Integer read FID write FID;
    [TAttrTest]
    constructor Create;
    [TAttrTest]
    destructor Destroy; override;
    [TAttrTest]
    procedure DoThis;
  end;

var
  [TAttrTest]
  I : Integer;

Так как же работают атрибуты в Delphi 2010?
Атрибуты должны наследоваться от TCustomAttribute, и если вы посмотрите на описание TCustomAttribute, то вы не найдете там ничего особенного.

{Базовый класс для всех пользовательских атрибутов. Экземпляры атрибутов создаются RTTI модулем,
и являются собственностью тех членов, к которым они применяются}
TCustomAttribute = class(TObject)
end;

Задавать только имя для нового атрибута имеет смысл лишь в редких случаях, обычно вам нужно привязать какие-то данные. Это делается посредством конструктора. Следующий пример показывает, как сделать вызов конструктора в атрибуте.

Type
  TAttrTest2 = class(TObject)
  private
     FId : Integer;
  public
     constructor Create(aID : Integer);
     property ID : Integer read FID write FID;
  end;

  [TAttrTest2(123)]
  TMyObject = Class(TObject)
  end;

Это сделано исключительно для того, что бы объявить Атрибут и "украсить" им ваш тип. Доступ к значению атрибутов осуществляется с помощью rtti.pas, общие основы того как это работает я описал в предыдущем посте.
Для всех элементов, которые могут иметь атрибуты, имеется методом .GetAttributes(), который возвращает массив атрибутов, связанных с соответствующим элементом.

Следующий код показывает, как осуществлять доступ к атрибутам.

program Project10;

{$APPTYPE CONSOLE}

uses
  SysUtils, RTTI;
type
  TAttrTest2 = class(TCustomAttribute)
  private
     FId : Integer;
  public
     constructor Create(aID : Integer);
     property ID : Integer read FID write FID;
  end;

  [TAttrTest2(1)]
  [TAttrTest2(2)]
  [TAttrTest2(3)]
  TMyObject = Class(TObject)
  end;

{ TAttrTest2 }

constructor TAttrTest2.Create(aID: Integer);
begin
 FID := aId;
end;

var
 c : TRttiContext;
 t : TRttiType;
 a : TCustomAttribute;
begin
   c := TRttiContext.Create;
   try
     t := c.GetType(TMyObject);
     for a in  t.GetAttributes do
     begin
       Writeln((a as TAttrTest2).ID);
     end;
   finally
     c.Free
   end;
   readln;
end.

Результат:

1
2
3
Кроме того, атрибуты имеют несколько других специфических особенностей, реализованных в компиляторе.
Допустим, у вас есть атрибут, поименованный следующим образом…

type
TestAttribute = class(TCustomAttribute)
end;

// На него можно сослаться двумя различными способами:

[TestAttribute]
TExample = class(Tobject)
end;

[Test]
TExample2 = class(TObject)
end;

Компилятор ищет соответствующий тип, и если не находит, то автоматически добавляет "Attribute" к имени, и снова начинает искать. Это сделано для того, что бы сымитировать поведение .Net.
Компилятор так же реализует несколько специфическую поддержку типов, позволяющую вам легко получать TRttiType через указатель pTypeInfo.

uses
  SysUtils, Rtti;

type
  TestAttribute = class(TCustomAttribute)
  public
    constructor Create(aType : TRttiType);
  end;

  [Test(typeinfo(Integer))]
  TEmployee = class(TObject)
  end;

Существует много возможностей практического применения Атрибутов, о которых я расскажу в следующих статьях.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 14.10.2009 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Enterprise Connectors (1 Year term)
Delphi Professional Named User
erwin Data Modeler Workgroup Edition r9.7 - Product plus 1 Year Enterprise Maintenance Commercial
Kaspersky Endpoint Security для бизнеса – Стандартный Russian Edition. 10-14 Node 1 year Base License
Stimulsoft Reports Server Team 10 users
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Краткие описания программ и ссылки на них
Работа в Windows и новости компании Microsoft
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100