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

Материал из ТХАБ.РФ
Перейти к: навигация, поиск
м (Написание собственного атрибута и его использование)
м (Применение атрибутов)
 
(не показано 16 промежуточных версий 2 участников)
Строка 1: Строка 1:
В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования.
+
В языке [[Перфолента.Net]] можно привязать к элементам программы (модулям, полям, функциям) дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования. У атрибута нет логики, он просто хранит несколько значений, что бы их можно было прочитать в будущем. Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей.  
  
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются  
+
Фактически '''Атрибут - это метка''' которую можно прикрепить к полю, функции, методу, самой программе (сборке) или модулю программы (DLL) значение которой сможет прочитать другой компонент этой или другой программы:
 +
 
 +
Значение присвоенное атрибуту '''ИмяАтрибута''' процедуры '''ИмяПроцедуры''' сможет прочитать любая программа, которая обратится к программе содержащей процедуру '''ИмяПроцедуры''' т.е. внешняя программа прочитав значение атрибута ИмяАтрибута у процедуры ИмяПроцедуры получит значение "ЗачениеАтрибута" которое сможет использовать по своему усмотрению.
 +
 +
• [[Перфолента.NET. ООП. Как написать свой атрибут|Как написать свой атрибут]]
 +
 
 +
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются:
 
* на стадии компиляции
 
* на стадии компиляции
 
* на стадии выполнения
 
* на стадии выполнения
 
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.
 
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.
  
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).
+
Процесс '''получения''' атрибутов сборки и других элементов программы называется рефлексией (reflection).
  
 
== Виды атрибутов ==
 
== Виды атрибутов ==
Строка 13: Строка 19:
 
* выполнение кода программы
 
* выполнение кода программы
  
Атрибуты могут быть определены:
+
Атрибуты определены:
 
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков
 
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков
 
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку  
 
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку  
Строка 27: Строка 33:
  
 
== Применение атрибутов ==
 
== Применение атрибутов ==
 +
Наиболее популярные и простые в использовании атрибуты:
  
== Написание собственного атрибута и его использование ==
+
* [[&ВидноВсем]] -  атрибуты видимости классов и их членов, к полю, функции, методу, объекту - могут обращаться другие объекты
 +
* [[&ОбщийДляКласса]] - [[Поле]] существует в 1-м экземпляре, для всех объектов данного типа (Класса)
 +
* [[&ТолькоЧтение]], [[&ТолькоЗапись]] - атрибуты ограничения доступа к полям и свойствам объекта
 +
* [[&ИмпортМетода]] – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру
  
У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем.
+
Примеры использования:
 +
Класс Лампа
 +
        // Поля класса
 +
        &ВидноВсем
 +
        Поле Состояние тип Строка = "Выключена" // Переменная имеющая атрибут &ВидноВсем
  
Например, Атрибут - '''АнглийскийСиноним''' может использоваться компилятором, если пользователь вдруг решил писать код на английском языке, тогда компилятор будет искать метод не только по именам, но и по синонимам.
+
    &ВидноВсем
 
+
    Функция ИмяФункции // Функция имеющая атрибут &ВидноВсем
В стандартной библиотеке Перфоленты почти для всех классов и их членов определены английские синонимы, но компилятор пока ими не умеет ими пользоваться (зарезервировано на будущее)
+
      ----
 
+
    КонецФункции
Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей.
 
 
 
Например:
 
* редактор формы может показывать в палитре свойств только те свойства формы у которых буде установлен атрибут '''РедактируетсяВПалитреСвойств''' или не будет атрибута '''УстаревшееСвойство'''
 
 
 
* Программа тестирования может запускать только те методы у которых установлен атрибут '''Тестировать'''.
 
 
 
* Программа выгрузки класса может выгружать только те поля у которых есть атрибут '''Выгружать''' и т.д. применений можно много найти...
 
 
 
Определим простейший атрибут '''АнглийскийСиноним''':
 
 
 
&ВидноВсем
 
Класс АнглийскийСиноним Родитель Атрибут
 
        Поле _Синоним тип Строка
 
        &ВидноВсем
 
        Конструктор(Синоним тип Строка)
 
                _Синоним = Синоним
 
        КонецКонструктора
 
        &ВидноВсем
 
        Функция ПолучитьСиноним() тип Строка
 
                Возврат _Синоним
 
        КонецФункции
 
КонецКласса
 
 
 
Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.
 
 
 
Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:
 
 
 
&АнглийскийСиноним("Start"), ВидноВсем
 
Процедура Старт
 
        //тут какой-то код
 
КонецПроцедуры
 
 
 
Мы задали для процедуры Старт два атрибута, один созданный нами - АнглийскийСиноним, а другой встроенный - ВидноВсем. Английский синоним процедуры Старт сможет узнать любая программа (в том числе и эта), которая захочет исследовать сборку программы содержащей процедуру.
 
 
 
Непонятно как использовать Атирбут АнглийскийСиноним, как он влияет на выполнение программы ??
 
 
 
Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом.
 
Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:
 
 
 
&Атрибут1, Атрибут2, АтрибутН  ЭлементПрограммы...
 
 
 
Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:
 
 
&Атрибут1, Атрибут2, АтрибутН
 
ЭлементПрограммы...
 
 
 
Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.
 
 
 
В конструктор атрибута можно передать необходимое количество параметров:
 
 
 
&Новый ContextClass("МойКласс", "MyClass")
 
Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:
 
 
&ContextClass("МойКласс", "MyClass")
 
 
 
После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:
 
 
 
&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}
 
 
 
Значениями параметров конструктора, полей и свойств могут быть только константные не изменяемые  в дальнейшем выражения, вычисляемые при компиляции.
 
 
//в этом атрибуте проверим вычисление константных выражений в параметрах
 
&EnumerationType("Виды"+"Операци"+"и"с,  "Operation"+"Types",  Не Ложь)
 
 
 
Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:
 
 
&Новый ВидноВсем(){}, Новый ВидноСборке(){}
 
 
 
Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:
 
 
 
&ВидноВсем, ВидноСборке
 
  
 
== Встроенные атрибуты языка Перфолента ==
 
== Встроенные атрибуты языка Перфолента ==
Строка 113: Строка 55:
 
В язык Перфолента встроены следующие атрибуты:
 
В язык Перфолента встроены следующие атрибуты:
  
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;
+
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов
  
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;
+
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс
  
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;
+
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов
  
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;
+
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса
  
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы
+
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы
  
 
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса
 
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса
  
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;
+
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования
  
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;
+
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения
  
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;
+
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике
  
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;
+
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике
  
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;
+
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами
  
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;
+
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам
  
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;
+
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события
  
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;
+
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру
  
 
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым  
 
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым  
 
применяются конкретные атрибуты
 
применяются конкретные атрибуты
  
== Атрибуты NET Framework и их использование ==
+
== См. также  ==
+
* [[Перфолента.NET. ООП. Атрибуты Net Farmework]]
=== Атрибуты сборки (.NET) ===
+
* [[Перфолента.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)===
 
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.
 
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.
 
# Описание свойств COM для классов, методов и интерфейсов.
 
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).
 
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.
 
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).
 
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.
 
# Описание требований безопасности для методов.
 
# Указание характеристик, используемых для обеспечения безопасности.
 
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.
 
# Получение информации о вызывающем методе.
 
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.
 
 
 
Использование атрибутов в указанных случаях описано в документации .Net.
 
 
 
== Устройство атрибута ==
 
 
 
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.
 
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров.  Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами:
 
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,
 
а также это может быть Перечисление одного из указанных типов.
 
 
 
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.
 
  
 +
== Ссылки ==
 +
* http://promcod.com.ua/Article.asp?code=20201106234710055491 Первоисточник
  
 
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]
 
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]
 
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]
 
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]

Текущая версия на 19:38, 12 ноября 2020

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

Фактически Атрибут - это метка которую можно прикрепить к полю, функции, методу, самой программе (сборке) или модулю программы (DLL) значение которой сможет прочитать другой компонент этой или другой программы:

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

Как написать свой атрибут

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Примеры использования:

Класс Лампа 
        // Поля класса 
        &ВидноВсем
        Поле Состояние тип Строка = "Выключена" // Переменная имеющая атрибут &ВидноВсем
   &ВидноВсем
   Функция ИмяФункции // Функция имеющая атрибут &ВидноВсем
     ----
   КонецФункции

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

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

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

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

См. также

Ссылки