Перфолента.NET. ООП. Атрибуты элементов программы — различия между версиями

Материал из ТХАБ.РФ
Перейти к: навигация, поиск
м (Использование атрибутов (.NET Framework))
м
Строка 1: Строка 1:
 
В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования.
 
В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования.
  
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются как на стадии компиляции, так и на стадии выполнения. Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.
+
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются  
 +
* на стадии компиляции
 +
* на стадии выполнения
 +
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.
  
 
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).
 
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).
Строка 22: Строка 25:
  
 
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.
 
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.
 +
 +
== Применение атрибутов ==
 +
 +
== Написание собственного атрибута и его использование ==
 +
 +
Определим простейший атрибут АнглийскийСиноним:
 +
 +
&ВидноВсем
 +
Класс АнглийскийСиноним Родитель Атрибут
 +
        Поле _Синоним тип Строка
 +
        &ВидноВсем
 +
        Конструктор(Синоним тип Строка)
 +
                _Синоним = Синоним
 +
        КонецКонструктора
 +
        &ВидноВсем
 +
        Функция ПолучитьСиноним() тип Строка
 +
                Возврат _Синоним
 +
        КонецФункции
 +
КонецКласса
 +
 +
Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.
 +
 +
Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:
 +
 +
&АнглийскийСиноним("Start"), ВидноВсем
 +
Процедура Старт
 +
        //тут какой-то код
 +
КонецПроцедуры
 +
 +
Мы задали для процедуры Старт два атрибута, один созданный нами - АнглийскийСиноним, а другой встроенный - ВидноВсем. Английский синоним процедуры Старт сможет узнать любая программа (в том числе и эта), которая захочет исследовать сборку программы содержащей процедуру.
 +
 +
Непонятно как использовать Атирбут АнглийскийСиноним, как он влияет на выполнение программы ??
 +
 +
Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом.
 +
Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:
 +
 +
&Атрибут1, Атрибут2, АтрибутН  ЭлементПрограммы...
 +
 +
Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:
 +
 +
&Атрибут1, Атрибут2, АтрибутН
 +
ЭлементПрограммы...
 +
 +
Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.
 +
 +
В конструктор атрибута можно передать необходимое количество параметров:
 +
 +
&Новый ContextClass("МойКласс", "MyClass")
 +
Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:
 +
 +
&ContextClass("МойКласс", "MyClass")
 +
 +
После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:
 +
 +
&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}
 +
 +
Значениями параметров конструктора, полей и свойств могут быть только константные не изменяемые  в дальнейшем выражения, вычисляемые при компиляции.
 +
 +
//в этом атрибуте проверим вычисление константных выражений в параметрах
 +
&EnumerationType("Виды"+"Операци"+"и"с,  "Operation"+"Types",  Не Ложь)
 +
 +
Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:
 +
 +
&Новый ВидноВсем(){}, Новый ВидноСборке(){}
 +
 +
Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:
 +
 +
&ВидноВсем, ВидноСборке
  
 
== Встроенные атрибуты языка Перфолента ==
 
== Встроенные атрибуты языка Перфолента ==

Версия 14:52, 12 ноября 2020

В языке Перфолента.Net можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования.

В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются

  • на стадии компиляции
  • на стадии выполнения

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

Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).

Виды атрибутов

Итак, Атрибуты могут влиять на:

  • сборку (компиляцию) программы
  • выполнение кода программы

Атрибуты могут быть определены:

  • в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков
  • в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку
  • Вами в вашей программе и использовать их будете только Вы

Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:

  • видимости (ВидноВсем),
  • наследования,
  • переопределения методов
  • и другие (ТолькоДляЧтения).

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

Применение атрибутов

Написание собственного атрибута и его использование

Определим простейший атрибут АнглийскийСиноним:

&ВидноВсем
Класс АнглийскийСиноним Родитель Атрибут
       Поле _Синоним тип Строка
       &ВидноВсем
       Конструктор(Синоним тип Строка)
               _Синоним = Синоним
       КонецКонструктора
       &ВидноВсем
       Функция ПолучитьСиноним() тип Строка
               Возврат _Синоним
       КонецФункции
КонецКласса

Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.

Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:

&АнглийскийСиноним("Start"), ВидноВсем
Процедура Старт
       //тут какой-то код
КонецПроцедуры

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

Непонятно как использовать Атирбут АнглийскийСиноним, как он влияет на выполнение программы ??

Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом. Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:

&Атрибут1, Атрибут2, АтрибутН   ЭлементПрограммы...

Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:

&Атрибут1, Атрибут2, АтрибутН
ЭлементПрограммы...

Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.

В конструктор атрибута можно передать необходимое количество параметров:

&Новый ContextClass("МойКласс", "MyClass")

Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:

&ContextClass("МойКласс", "MyClass")

После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:

&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}

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

//в этом атрибуте проверим вычисление константных выражений в параметрах
&EnumerationType("Виды"+"Операци"+"и"с,   "Operation"+"Types",   Не Ложь)

Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:

&Новый ВидноВсем(){}, Новый ВидноСборке(){}

Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:

&ВидноВсем, ВидноСборке

Встроенные атрибуты языка Перфолента

В язык Перфолента встроены следующие атрибуты:

  • ВидноВсем, ВидноСборке, ВидноНаследникам, ВидноНаследникамСборки - атрибуты видимости классов и их членов;
  • ПространствоИмен("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;
  • ОднопоточнаяМодель, МногопоточнаяМодель - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;
  • ОбщийДляКласса - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;
  • Глобальный - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы;
  • Сериализуемый – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса
  • ДолженНаследоваться, МожетНаследоваться, НеМожетНаследоваться - атрибуты класса, определяющие возможность или необходимость его наследования;
  • ДолженПереопределяться, МожетПереопределяться, НеМожетПереопределяться - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;
  • Переопределение - атрибут переопределения метода родителя в классе-наследнике;
  • Перекрытие - атрибут перекрытия метода родителя в классе-наследнике;
  • Перегрузка - атрибут перегрузки методов с одинаковыми именами;
  • ТолькоЧтение, ТолькоЗапись - атрибуты ограничения доступа к полям и свойствам;
  • Обработчик("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;
  • ИмпортМетода – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;

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

Атрибуты NET Framework и их использование

Атрибуты сборки (.NET)

В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов.

АтрибутСборки   System.Runtime.InteropServices.ComVisible(Ложь)

Атрибуты модуля сборки (.NET)

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

АтрибутМодуля   System.CLSCompliant(Истина)

Атрибуты параметров метода.

Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.

&ВидноВсем
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,
                     &АнглСиноним("LowDigits")  Знач МладшиеРазряды тип Бит16
                     ) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты
   Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды
КонецФункции

Определение особого порядка и правил передачи полей структуры (NET)

Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.

&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }
Структура UDT
   &ВидноВсем Поле rxStatus тип Цел16
   &ВидноВсем Поле datalen тип Байт
   &ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }
   Поле array1 тип Байт[]
   &ВидноВсем
   Процедура Инициализировать()
       //код инициализации
   КонецПроцедуры
КонецСтруктуры

Наиболее актуальные случаи применения атрибутов (NET)

  1. Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.
  2. Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.
  3. Описание свойств COM для классов, методов и интерфейсов.
  4. Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).
  5. Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.
  6. Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).
  7. Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.
  8. Описание требований безопасности для методов.
  9. Указание характеристик, используемых для обеспечения безопасности.
  10. Установка параметров JIT компиляции, например, для сохранения удобства отладки.
  11. Получение информации о вызывающем методе.
  12. Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.

Использование атрибутов в указанных случаях описано в документации .Net.

Устройство атрибута

Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute. Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип, а также это может быть Перечисление одного из указанных типов.

К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.