Что такое атрибут в программировании
Перейти к содержимому

Что такое атрибут в программировании

  • автор:

Атрибуты (F#)

Атрибуты позволяют применять метаданные к конструкции программирования.

Синтаксис

Remarks

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

Attribute-name ссылается на имя (возможно, квалифицируется пространствами имен) допустимого типа атрибута с суффиксом или без суффикса Attribute , который обычно используется в именах типов атрибутов. Например, тип ObsoleteAttribute можно сократить только Obsolete в этом контексте.

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

property-name = property-value 

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

open System.Runtime.InteropServices [] extern bool CloseHandle(nativeint handle) 

В этом примере атрибутом является DllImportAttribute , здесь используется в сокращенном виде. Первый аргумент является позициональным параметром, а второй — свойством .

Атрибуты — это программная конструкция .NET, которая позволяет связать объект, известный как атрибут , с типом или другим программным элементом. Элемент программы, к которому применяется атрибут, называется целевым объектом атрибута. Атрибут обычно содержит метаданные о своем целевом объекте. В этом контексте метаданными могут быть любые данные о типе, отличные от его полей и членов.

Атрибуты в F# можно применять к следующим конструкциям программирования: функциям, методам, сборкам, модулям, типам (классы, записи, структуры, интерфейсы, делегаты, перечисления, объединения и т. д.), конструкторам, свойствам, полям, параметрам типа и возвращаемым значениям. Атрибуты не допускаются для let привязок внутри классов, выражений или выражений рабочих процессов.

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

[] [] type SomeType1 = 

Вы можете запрашивать атрибуты во время выполнения с помощью отражения .NET.

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

[] type SomeType2 = 

Обычно встречаются атрибуты Obsolete , атрибуты для обеспечения безопасности, атрибуты для поддержки COM, атрибуты, связанные с владением кодом, и атрибуты, указывающие, можно ли сериализовать тип. В следующем примере показано использование атрибута Obsolete .

open System [] let obsoleteFunction x y = x + y let newFunction x y = x + 2 * y // The use of the obsolete function produces a warning. let result1 = obsoleteFunction 10 100 let result2 = newFunction 10 100 

Для целевых объектов assembly атрибутов и module атрибуты применяются к привязке верхнего уровня do в сборке. Вы можете включить слово assembly или «module« в объявление атрибута следующим образом:

open System.Reflection [] [] do printfn "Executing. " 

Если опустить целевой объект атрибута для атрибута, применяемого do к привязке, компилятор F# попытается определить целевой объект атрибута, который имеет смысл для этого атрибута. Многие классы атрибутов имеют атрибут типа System.AttributeUsageAttribute , который содержит сведения о возможных целевых объектах, поддерживаемых для этого атрибута. System.AttributeUsageAttribute Если атрибут указывает, что атрибут поддерживает функции в качестве целевых объектов, атрибут принимается для применения к main точке входа программы. System.AttributeUsageAttribute Если атрибут указывает, что атрибут поддерживает сборки в качестве целевых объектов, компилятор принимает атрибут для применения к сборке. Большинство атрибутов не применяются как к функциям, так и к сборкам, но в случаях, когда это происходит, атрибут применяется к main функции программы. Если целевой объект атрибута указан явно, атрибут применяется к указанному целевому объекту.

Хотя обычно не требуется явно указывать целевой объект атрибута, допустимые значения целевого объекта в атрибуте вместе с примерами использования приведены в следующей таблице:

let function1 x : [] int = x + 1 
[] val mutable x: int 
[] this.MyProperty = x 

Атрибутивное программирование. Часто задаваемые вопросы

HRESULT — это простой тип данных, который часто используется в качестве возвращаемого значения атрибутами и ATL в целом. В следующей таблице описаны различные значения. Дополнительные значения содержатся в файле заголовка winerror.h.

Имя Описание Значение
S_OK Операция выполнена успешно 0x00000000
E_UNEXPECTED Непредвиденный сбой 0x8000FFFF
E_NOTIMPL Не реализовано 0x80004001
E_OUTOFMEMORY Не удалось выделить необходимую память 0x8007000E
E_INVALIDARG Один или несколько аргументов недопустимы 0x80070057
E_NOINTERFACE Такой интерфейс не поддерживается 0x80004002
E_POINTER Недопустимый указатель 0x80004003
E_HANDLE Недопустимый дескриптор 0x80070006
E_ABORT Операция прервана 0x80004004
E_FAIL Неуказанный сбой 0x80004005
E_ACCESSDENIED Общая ошибка отказа в доступе 0x80070005

Когда нужно указать имя параметра для атрибута?

В большинстве случаев, если атрибут имеет один параметр, этот параметр называется. Это имя не требуется при вставке атрибута в код. Например, следующее использование агрегируемого атрибута:

[coclass, aggregatable(value=allowed)] class CMyClass < // The class declaration >; 

точно так же, как:

[coclass, aggregatable(allowed)] class CMyClass < // The class declaration >; 

Однако следующие атрибуты имеют одинарные неименованные параметры:

Можно ли использовать комментарии в блоке атрибутов?

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

[ coclass, progid("MyClass.CMyClass.1"), /* Multiple-line comment */ threading("both") // Single-line comment ] 
[ coclass, progid("MyClass.CMyClass.1" /* Multiple-line comment */ ), threading("both" // Single-line comment) ] 

Как атрибуты взаимодействуют с наследованием?

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

Как использовать атрибуты в неатрибуционном проекте ATL?

Возможно, у вас есть неатрибуционный проект ATL, имеющий IDL-файл, и вы можете начать добавлять объекты с атрибутами. В этом случае используйте мастер добавления классов для предоставления кода.

Как использовать IDL-файл в проекте с атрибутами?

У вас может быть IDL-файл, который вы хотите использовать в проекте атрибутов ATL. В этом случае вы будете использовать атрибут importidl, скомпилируйте IDL-файл в H-файл (см. страницы свойств MIDL в диалоговом окне страниц свойств проекта), а затем включите H-файл в проект.

Можно ли изменить код, который внедряется атрибутом?

Некоторые атрибуты внедряют код в проект. Вы можете просмотреть внедренный код с помощью параметра компилятора /Fx . Также можно скопировать код из внедренного файла и вставить его в исходный код. Это позволяет изменить поведение атрибута. Однако может потребоваться изменить другие части кода.

Следующий пример является результатом копирования внедренного кода в файл исходного кода:

// attr_injected.cpp // compile with: comsupp.lib #define _ATL_ATTRIBUTES 1 #include #include [ module(name="MyLibrary") ]; // ITestTest [ object, uuid("DADECE00-0FD2-46F1-BFD3-6A0579CA1BC4"), dual, helpstring("ITestTest Interface"), pointer_default(unique) ] __interface ITestTest : IDispatch < [id(1), helpstring("method DoTest")] HRESULT DoTest([in] BSTR str); >; // _ITestTestEvents [ uuid("12753B9F-DEF4-49b0-9D52-A79C371F2909"), dispinterface, helpstring("_ITestTestEvents Interface") ] __interface _ITestTestEvents < [id(1), helpstring("method BeforeChange")] HRESULT BeforeChange([in] BSTR str, [in,out] VARIANT_BOOL* bCancel); >; // CTestTest [ coclass, threading(apartment), vi_progid("TestATL1.TestTest"), progid("TestATL1.TestTest.1"), version(1.0), uuid("D9632007-14FA-4679-9E1C-28C9A949E784"), // this line would be commented out from original file // event_source("com"), // this line would be added to support injected code source(_ITestTestEvents), helpstring("TestTest Class") ] class ATL_NO_VTABLE CTestTest : public ITestTest, // the following base classes support added injected code public IConnectionPointContainerImpl, public IConnectionPointImpl  < public: CTestTest() < >// this line would be commented out from original file // __event __interface _ITestTestEvents; DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct() < return S_OK; >void FinalRelease() <> public: CComBSTR m_value; STDMETHOD(DoTest)(BSTR str) < VARIANT_BOOL bCancel = FALSE; BeforeChange(str,&bCancel); if (bCancel) < return Error("Error : Someone don't want us to change the value"); >m_value =str; return S_OK; > // the following was copied in from the injected code. HRESULT BeforeChange(::BSTR i1. VARIANT_BOOL* i2) < HRESULT hr = S_OK; IConnectionPointImpl* p = this; VARIANT rgvars[2]; Lock(); IUnknown** pp = p->m_vec.begin(); Unlock(); while (pp < p->m_vec.end()) < if (*pp != NULL) < IDispatch* pDispatch = (IDispatch*) *pp; ::VariantInit(&rgvars[1]); rgvars[1].vt = VT_BSTR; V_BSTR(&rgvars[1])= (BSTR) i1; ::VariantInit(&rgvars[0]); rgvars[0].vt = (VT_BOOL | VT_BYREF); V_BOOLREF(&rgvars[0])= (VARIANT_BOOL*) i2; DISPPARAMS disp = < rgvars, NULL, 2, 0 >; VARIANT ret_val; hr = __ComInvokeEventHandler(pDispatch, 1, 1, &disp, &ret_val); if (FAILED(hr)) break; > pp++; > return hr; > BEGIN_CONNECTION_POINT_MAP(CTestTest) CONNECTION_POINT_ENTRY(__uuidof(::_ITestTestEvents)) END_CONNECTION_POINT_MAP() // end added code section // _ITestCtrlEvents Methods public: >; int main() <> 

Как перенаправить объявление интерфейса атрибута?

Если вы собираетесь сделать перенаправленное объявление интерфейса с атрибутами, необходимо применить те же атрибуты к объявлению пересылки, которое применяется к фактическому объявлению интерфейса. Кроме того, необходимо применить атрибут экспорта к объявлению пересылки.

Можно ли использовать атрибуты для класса, производного от класса, который также использует атрибуты?

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

Программирование с помощью атрибутов

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

Идея аннотирования программного кода с помощью атрибутов не нова. Множество встроенных атрибутов предлагает COM IDL (Interface Definition Language – язык описания интерфейсов), что позволяет разработчику описывать типы COM-сервера. Однако атрибуты COM представляют собой, по сути, лишь набор ключевых слов. Если перед разработчиком COM возникает задача создания пользовательских атрибутов, то эта задача оказывается вполне разрешимой, но ссылаться на такой атрибут в программном коде придется с помощью 128-разрядного номера (GUID), а это, в лучшем случае, слишком обременительно.

В отличие от атрибутов COM IDL (которые, напомним, являются просто ключевыми словами), атрибуты .NET являются типами класса, расширяющими абстрактный базовый класс System.Attribute. При исследовании пространств имен .NET вы можете обнаружить множество встроенных атрибутов, которые можно использовать в приложениях. К тому же вы можете строить свои пользовательские атрибуты, чтобы затем корректировать поведение своих типов с помощью создания новых типов, производных от Attribute.

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

Читайте также

Селекторы атрибутов

Селекторы атрибутов CSS позволяет создавать правила, сопоставляемые элементам с атрибутами, определенными в исходном коде HTML-документа. Селекторы атрибутов могут сопоставляться в следующих четырех случаях.• [att] – если для элемента установлен атрибут att независимо от

ГЛАВА 12 Сетевое программирование с помощью сокетов Windows

ГЛАВА 12 Сетевое программирование с помощью сокетов Windows Именованные каналы пригодны для организации межпроцессного взаимодействия как в случае процессов, выполняющихся на одной и той же системе, так и в случае процессов, выполняющихся на компьютерах, связанных друг с

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

Выбор атрибутов Как было показано в главе 3, «Создание и применение шаблонов», можно выбирать атрибуты, если предварять их имена префиксом @. Вы уже работали с атрибутом UNITS, который поддерживают большинство детей элементов <PLANET>:<PLANET> <NAME>Earth</NAME> <MASS UNITS=»(Earth =

Глава 6 Программирование с помощью стандартных функций ввода-вывода

Глава 6 Программирование с помощью стандартных функций ввода-вывода До сих пор мы использовали существующие инструменты, чтобы разрабатывать новые, но сейчас уже достигнут разумный предел в создании новых средств с помощью shell, sed и awk. В этой главе нам предстоит написать

1.3. Установка атрибутов

1.3. Установка атрибутов Для того чтобы ваша схема последовательной цепи точно соответствовала образцу на рис. 1.5, нужно дать сопротивлениям и источнику напряжения необходимые имена и указать их характеристики. При работе с редактором SCHEMATICS имена, значения и другие

Программирование баз данных с помощью Access

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

ГЛАВА 12. Отображение типов, динамическое связывание и программирование с помощью атрибутов

ГЛАВА 12. Отображение типов, динамическое связывание и программирование с помощью атрибутов Как показано в предыдущей главе, компоновочные блоки являются базовыми элементами установки и среде .NET. С помощью интегрированного обозревателя объектов в Visual Studio 2005 можно

Потребители атрибутов

Потребители атрибутов Как вы можете догадаться, в комплекте с .NET Framework 2.0 SDK поставляется множество утилит, предназначенных для работы с различными атрибутами. Даже компилятор C# (csc.exe) запрограммирован на проверку определенных атрибутов в процессе компиляции. Например,

Программирование с помощью таймеров обратного вызова

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

Роль атрибутов CIL

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

Настройка параметров сериализации с помощью атрибутов

Настройка параметров сериализации с помощью атрибутов Хотя реализация интерфейса ISerializable в .NET 2.0 все еще допустима, для настройки процесса сериализации теперь более предпочтительным считается определение методов, наделенных одним из целого ряда новых атрибутов,

7. Унификация атрибутов

7. Унификация атрибутов Если при миграции первичных ключей некоего родительского класса сущностей в один и тот же дочерний класс попадают совпадающие по смыслу атрибуты из разных родительских классов, то эти атрибуты необходимо «слить», т. е. необходимо провести так

Узлы атрибутов

Узлы атрибутов Атрибутам того или иного элемента соответствуют узлы атрибутов. Считается, что узел элемента является родителем узла своего атрибута, но вместе с тем узел атрибута не является дочерним узлом узла его элемента. Такая ситуация несколько отличает дерево

Глава 12 Программирование с помощью процедур VBA

Глава 12 Программирование с помощью процедур VBA Как уже говорилось, VBA – это объектно-ориентированный язык программирования. В свое время он был разработан специально для записи макросов в Microsoft Excel 5.0. Затем он начал использоваться и другими приложениями Microsoft Office, в

Программирование приложений с помощью VBA

Программирование приложений с помощью VBA Что может делать пользователь с помощью VBA? Ответ очень прост: все. К сожалению, ни в одной книге нельзя рассмотреть все вероятные сферы программирования, в которых вы найдете применение возможностям VBA. Поэтому ограничимся тем, что

Attribute (атрибут)

Атрибутом называется описание поименованного слота определенного типа какого-либо класса. Каждый объект этого класса содержит отдельное значение для данного типа.

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

У атрибута есть несколько основных составляющих. Их подробное описание вы найдете в отдельных статьях нашей «Энциклопедии». Ниже мы перечислим их с кратким пояснением.

changeable

Выражение, определяющее то значение, которое атрибут получает сразу после инициализации объекта. Само выражение представляет собой строку текста с указанием названия языка, на котором следует интерпретировать выражение. Интерпретация выражения происходит в контексте этого языка в момент создания экземпляра объекта. См. более подробно в статье энциклопедии expression. Наличие исходного значения необязательно. Если оно отсутствует, то в статической модели не определяется значение атрибута для вновь созданного объекта. (В таком случае это значение может задаваться в какой-либо другой части модели.)
Обратите внимание, что процедура явного создания экземпляров (например, конструктор) может замещать исходное значение атрибута.
Исходное значение атрибута с областью действия в масштабе класса используется при его инициализации сразу же в начале выполнения. Язык UML не определяет относительный порядок инициализации разных атрибутов с областью действия в масштабе класса.

Имя атрибута. Строка, уникальная в данном классе и у его предков. Имя также не должно иметь дубликатов среди имен ролей ассоциации, доступных этому классу.

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

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

"стереотип"необяз видимость необяз имя множественность необяз: тип необяз = =исходное эначение обяз необяз

Видимость. Для изображения видимости служат пунктуационные знаки. Кроме этого, видимость может указываться с помощью ключевого слова, находящегося в строке свойств. Последний вариант используется в случае, когда это удобнее использовать в данном языке реализации или по желанию разработчика. Видимость бывает:
+ (открытая) Каждый класс, который видит этот класс, видит и атрибут
# (защищенная) Атрибут является видимым для класса или одного из его потомков
— (закрытая) Атрибут является видимым только для данного класса
Имя. Имя обозначается в строке идентификатора.
Тип. Тип атрибута указывается в текстовой строке, определяющей классификатор. Имя класса или типа данных является легитимным выражением, указывающим на тип данных, к которому должен принадлежать данный атрибут. Синтаксис выражения зависит от языка, на котором это выражение написано. В каждом языке есть свой синтаксис для построения новых, типов данных на основе простых. Например, в языке C++ есть синтаксис для указателей, массивов и функций. В языке Ada, кроме того, есть синтаксис для поддиапазонов (subranges). Язык выражения является частью внутренней модели системы, однако при этом не всегда указывается на диаграммах. Язык реализации либо должен быть известен для всей диаграммы системы, либо очевиден, исходя из синтаксиса выражений.
Строка с указанием типа атрибута может опускаться. При этом она все равно сохраняется в модели.
Множественность. Выражение, описывающее множественность, пишется в квадратных скобках после имени атрибута. Если множественность атрибута представляет собой «ровно один», то ее можно не указывать, так как она означает, что у каждого объекта есть только один слот, содержащий значение данного типа (наиболее распространенный случай). Во всех других случаях множественность должна быть указана. См. статью энциклопедии multiplicity, в которой содержится полное обсуждение синтаксиса множественности.
Например:

colors [3]: Saturation Массив из трех насыщенностей цвета noints [2..*]: Point Массив из двух или более точек

Обратите внимание, что множественность вида 0..1 позволяет использовать значения null — то есть отсутствие значения. Значение null не входит в предметную область большинства типов данных. Таким образом, этот вид множественности дает возможность использовать значение, находящееся вне границ определенного типа данных. Значение null нередко является частью реализации указателей (однако даже в этом случае оно нередко используется условно. В языке С или C++ значение null относится к неопределенному значению для адресации памяти). Ниже вы видите объявление, которое позволяет различать значение null, и пустую строку. Такое различение поддерживают C++ и другие языки программирования.

name [0..1]: String Если имя (name) отсутствует, значит, используется значение null

Исходное значение. Исходное значение указывается строкой. Язык для интерпретации выражения при этом не указывается явно, но присутствует в модели. В случае отсутствия исходного значения строку и знак равенства можно опустить. Если множественность включает в себя нуль и при этом исходное значение не указано, атрибут инициализируется значением null (нулевое количество повторений).
Изменяемость. Изменяемость обозначается ключевым словом. По умолчанию используется значение changeable.
Именованное значение. К атрибуту, как и к любому другому элементу модели, можно добавлять именованные значения. Именованное значение имеет форму тег = значение, где тег — это имя, а значение — его содержание. Именованные значения вместе с ключевыми словами помешаются в отдельный список свойств, разделенных запятыми. Список берется в скобки.
Область действия. Атрибут с областью действия в масштабе класса помечается подчеркиванием имени и строки, содержащей выражение для типа данных. В противном случае этот атрибут актуален в масштабе экземпляра. Такая нотация основывается на том, что атрибут с областью действия в масштабе класса является значением для работающей системы точно так же, как и объект, — экземпляр класса. Таким образом, подчеркиванием выделяется и то и другое.
Class-scope-attribute
На рис. 32 представлены объявления некоторых атрибутов.

Рис. 32. Атрибуты

Варианты представления

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

Стилистические указания

Имена атрибутов пишутся обычным шрифтом.

Подобный синтаксис используется для описания квалификаторов, параметров шаблона и операций и т.д.
Обратите внимание, что семантически атрибут эквивалентен композиции. Впрочем, цель и использование того и другого, как правило, различны. Атрибуты используют с типами данных, то есть значениями, у которых нет собственной индивидуальности. Ассоциации используются с классами — значениями, у которых индивидуальность есть. Это разделение основывается на том, что объект, имеющий индивидуальность, должен прослеживать отношение в обоих направлениях, а для типов данных это не важно, так как они подчинены объектам.

Стандартные элементы

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *