Перейти к содержанию
Fire Monkey от А до Я
  • 0

Атрибуты в Delphi


rareMax

Вопрос

Кто может, расскажите о Атрибутах в делфи. Пытался гуглить - находил пару сайтов, которые перевели и по своему дополнили одну(!) заметку забугорную. Что на данный момент меня интересует:

  • В каких случаях желательно применять атрибуты
  • Действительно ли это удобно? 
  • Как я могу применять атрибуты в своем коде

Буду очень благодарен если кто то распишет как можно подробнее. 

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

Судя по всему, фишка довольно старая, но я ни разу не сталкивался с ее реальным применением.

Нашел такое описание с примером: http://habrahabr.ru/post/105776/

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

Ссылка на комментарий
  • 0

Судя по всему, фишка довольно старая, но я ни разу не сталкивался с ее реальным применением.

Нашел такое описание с примером: http://habrahabr.ru/post/105776/

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

На хабре я видел. Пример видел. Но хочу узнать где такое можно применять на практике.

Ссылка на комментарий
  • 0

насколько я разумею, атрибут это дополнительные свойства и даже методы, приаттаченные к объекту RTTI - классу, методу класса, полю

при работе мы можем учитывать это свойство

например, в этой библиотеке

при сериализации объекта в JSON можно переименовать поле, или убрать его из сериализации вовсе

в датаснап с помощью атрибутов сделана авторизация на исполнение метода

Ссылка на комментарий
  • 0

насколько я разумею, атрибут это дополнительные свойства и даже методы, приаттаченные к объекту RTTI - классу, методу класса, полю

при работе мы можем учитывать это свойство

например, в этой библиотеке

при сериализации объекта в JSON можно переименовать поле, или убрать его из сериализации вовсе

в датаснап с помощью атрибутов сделана авторизация на исполнение метода

Эх, где вы раньше были с этим примером - уже почти доделал свою обертку стандартного System.JSON для удобной работы. А у x-superobject со старту уже все красиво

Ссылка на комментарий
  • 0

я тоже сначала сделал стандартным, потом специально переделал

X-SO хорошо работает с вложенными в объект TObjectList

а у меня их много

Ссылка на комментарий
  • 0

Мы используем атрибуты для проверки через RTTI заполнено ли поле значением или нет:

unit TopologyPoint;

interface

uses
      SysUtils, Classes, Rtti,

      Spring.Container,

      //BL
      TopologyPointInterface,

      //Modules
      WhatElementAttribute
      ;

/// <summary>
///   Class for point primitive
/// </summary>
type
      TTopologyPoint = Class ( TInterfacedObject, ITopologyPoint )

      private

            {$REGION 'Fields'}

            /// <summary>
            /// Gets or sets X coordinate
            /// </summary>
            [TWhatElementAttribute ( TWhatElement.PublicField )]
            _x : Variant;

            /// <summary>
            /// Gets or sets Y coordinate
            /// </summary>
            [TWhatElementAttribute ( TWhatElement.PublicField )]
            _y : Variant;

            /// <summary>
            /// Gets or sets Z coordinate
            /// </summary>
            _z : Variant;

            {$ENDREGION}

            {$REGION 'Methods'}

            /// <summary>
            ///   Gets X
            /// </summary>
            /// <returns>X</returns>
            function GetX () : Variant;

            /// <summary>
            ///   Sets X
            /// </summary>
            /// <param name="value">X</param>
            procedure SetX ( const value : Variant );

            /// <summary>
            ///   Gets Y
            /// </summary>
            /// <returns>Y</returns>
            function GetY () : Variant;

            /// <summary>
            ///   Sets Y
            /// </summary>
            /// <param name="value">y</param>
            procedure SetY ( const value : Variant );

            /// <summary>
            ///   Gets Z
            /// </summary>
            /// <returns>Z</returns>
            function GetZ () : Variant;

            /// <summary>
            ///   Sets Z
            /// </summary>
            /// <param name="value">Z</param>
            procedure SetZ ( const value : Variant );

            /// <summary>
            ///   Gets empty flag of coordinates
            /// </summary>
            /// <returns>True if all coordinates are 0, false otherwise</returns>
            function GetEmptyFlag () : Boolean;

            {$ENDREGION}

      public

            {$REGION 'Properties'}

            /// <summary>
            ///   X coordinate
            /// </summary>
            property X : Variant read GetX write SetX;

            /// <summary>
            ///   Y coordinate
            /// </summary>
            property Y : Variant read GetY write SetY;

            /// <summary>
            ///   Z coordinate
            /// </summary>
            property Z : Variant read GetZ write SetZ;

            /// <summary>
            ///   Gets empty flag of coordinates
            /// </summary>
            property IsEmpty : Boolean read GetEmptyFlag;

            {$ENDREGION}

end;

implementation

{TTopologyPoint}

/// <summary>
///   Gets empty flag of coordinates
/// </summary>
/// <returns>True if all coordinates are 0, false otherwise</returns>
function TTopologyPoint.GetEmptyFlag () : Boolean;

      var
            context : TRttiContext;
            objectType : TRttiType;
            field : TRttiField;
            attribute : TCustomAttribute;
            found : Boolean;

begin

      context := TRTTIContext.Create ();
      objectType := context.GetType ( Self.ClassInfo );

      found := false;

      for field in objectType.GetFields do begin
            for attribute in field.GetAttributes do begin
                  if attribute is TWhatElementAttribute then begin
                        if ( attribute as TWhatElementAttribute ).Element = TWhatElement.PublicField then begin
                              if field.FieldType.Handle = TypeInfo ( String )  then begin
                                    if field.GetValue ( self ).ToString <> '' then begin
                                          found := true;
                                          break;
                                    end;
                              end;

                              if field.FieldType.Handle = TypeInfo ( Integer )  then begin
                                    if field.GetValue ( self ).ToString <> '0' then begin
                                          found := true;
                                          break;
                                    end;
                              end;

                              if field.FieldType.Handle = TypeInfo ( Extended )  then begin
                                    if field.GetValue ( self ).ToString <> '0' then begin
                                          found := true;
                                          break;
                                    end;
                              end;
                        end;
                  end;
            end;
      end;

      Result := not found;

end;

/// <summary>
///   Gets X
/// </summary>
/// <returns>X</returns>
function TTopologyPoint.GetX () : Variant;
begin

      Result := _x;

end;

/// <summary>
///   Sets X
/// </summary>
/// <param name="value">X</param>
procedure TTopologyPoint.SetX ( const value : Variant );
begin

      _x := value;

end;

/// <summary>
///   Gets Y
/// </summary>
/// <returns>Y</returns>
function TTopologyPoint.GetY () : Variant;
begin

      Result := _y;

end;

/// <summary>
///   Sets Y
/// </summary>
/// <param name="value">y</param>
procedure TTopologyPoint.SetY ( const value : Variant );
begin

      _y := value;

end;
/// <summary>
///   Gets Z
/// </summary>
/// <returns>Z</returns>
function TTopologyPoint.GetZ () : Variant;
begin

      Result := _z;

end;

/// <summary>
///   Sets Z
/// </summary>
/// <param name="value">Z</param>
procedure TTopologyPoint.SetZ ( const value : Variant );
begin

      _z := value;

end;

initialization

      GlobalContainer.RegisterType<TTopologyPoint>.Implements<ITopologyPoint>;

end.

А вот сам класс TWhatElement:

unit WhatElementAttribute;

interface

uses
     SysUtils, Classes;

/// <summary>
///   Attribute type enumeration
/// </summary>
type
      TWhatElement = ( PublicField, PublicProperty, PublicMethod );

/// <summary>
///   Class for attribute types
/// </summary>
type
      TWhatElementAttribute = class ( TCustomAttribute )

      private

            {$REGION 'Private fields'}

            /// <summary>
            ///   Element type instance
            /// </summary>
            _element : TWhatElement;

            {$ENDREGION}

      public

            {$REGION 'Properties'}

            /// <summary>
            ///   Property for element type instance
            /// </summary>
            property Element : TWhatElement read _element write _element;

            {$ENDREGION}

            {$REGION 'Constructors'}

            /// <summary>
            ///   Creates TWhatElementAttribute instance
            /// </summary>
            constructor Create ( const element : TWhatElement );

            {$ENDREGION}

end;

implementation

/// <summary>
///   Creates TWhatElementAttribute instance
/// </summary>
constructor TWhatElementAttribute.Create ( const element : TWhatElement );
begin

      _element := element;

end;

end.

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

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...