Понимание использования «Атрибутов»

Я пытаюсь понять использование Attributes немного лучше. Я это понимаю:

Теперь я хочу сделать еще кое-что с атрибутами и любопытно:

  • Как предопределенные атрибуты (например, DllImportAttribute или STAThread) выполняют свои функции? Потому что мы просто используем эти атрибуты и выполняем соответствующие функции. например С помощью DllImportAttribute я просто объявляю, что моему методу abc() нужен xyz.dll и загружается соответствующая DLL. Я не писал код для поиска и загрузки DLL xyz.dll.
  • Использовать среду выполнения .NET или компиляторы специально обрабатывать предопределенные атрибуты? Здесь под специальной обработкой я имел в виду, что доза .NET Runtime Environment или компиляторы обнаруживают, что в коде используются некоторые предопределенные атрибуты, и запускает соответствующий метод?
  • Если да, то как я могу предоставить/добавить такую ​​информацию с помощью среды выполнения .NET или компиляторов (даже если только на моем локальном ПК), чтобы он запускал специальный метод всякий раз, когда мой пользовательский атрибут используется в любом из проектов?

person cse    schedule 14.03.2018    source источник
comment
Я не знаю java и понятия не имею, в чем твоя проблема с атрибутами. Звучит для меня немного широко, лучше задайте 2 вопроса.   -  person Sinatr    schedule 14.03.2018
comment
Похоже, вы хотите использовать атрибуты, чтобы указать определенный код для запуска до/после/при условии при запуске метода, верно? Google для кодового контракта c#.   -  person Sinatr    schedule 14.03.2018
comment
@Sinatr Хорошо, я создал отдельный вопрос для аннотаций здесь. Я обновлю этот вопрос для C# (ясность кода и вопроса), так как по этому вопросу мы обсуждаем ответ @MichaelRandall для Attributes в C#.NET.   -  person cse    schedule 14.03.2018
comment
@MichaelRandall Я хочу понять, как я могу создать свой настраиваемый атрибут, чтобы среда выполнения .NET уведомляла меня всякий раз, когда мой настраиваемый атрибут используется в коде. Я обновил свой вопрос для большей ясности.   -  person cse    schedule 14.03.2018
comment
Неинтуитивное требование состоит в том, что должен быть какой-то код, использующий Reflection для возврата атрибута. Этот код часто очень хорошо спрятан. Как и [DllImport], встроенный в джиттер. [STAThread], встроенный в CLR. Также, скажем, [Browsable], встроенный в элемент управления PropertyGrid, [AssemblyVersion], встроенный в компилятор C#. Такой код отражения не может быть расширен простыми смертными. Так что запустить специальный метод не реально. Вы могли бы подумать о переписывании IL, PostSharp — это продукт, который делает это.   -  person Hans Passant    schedule 15.05.2018
comment
@HansPassant Спасибо за эту информацию. Можете дать ссылку на эту информацию?   -  person cse    schedule 15.05.2018
comment
postsharp.net   -  person Hans Passant    schedule 15.05.2018
comment
@HansPassant Я имел в виду Этот код часто очень хорошо спрятан. Как и [DllImport], встроенный в джиттер. [STAThread], встроенный в CLR. Также, скажем, [Browsable], встроенный в элемент управления PropertyGrid, [AssemblyVersion], встроенный в компилятор C#.   -  person cse    schedule 16.05.2018


Ответы (1)


На самом деле никакой тайны...

На самом деле атрибут — это объект, связанный с любым из следующих элементов: Assembly, Class, Method, Delegate, Enum, Event, Field, Interface, Property и Struct.

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

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

Из MSDN Атрибуты (C#)

Атрибуты предоставляют мощный метод связывания метаданных или декларативной информации с кодом (сборками, типами, методами, свойствами и т. д.). После того, как атрибут связан с программным объектом, атрибут может быть запрошен во время выполнения с использованием метода, называемого отражением. Дополнительные сведения см. в разделе Отражение (C#).

Атрибуты имеют следующие свойства:

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

  • Вы можете применить один или несколько атрибутов ко всем сборкам, модулям или меньшим элементам программы, таким как классы и свойства.

  • Атрибуты могут принимать аргументы так же, как методы и свойства.

Ваша программа может проверять свои собственные метаданные или метаданные в других программах с помощью отражения. Дополнительные сведения см. в разделе Доступ к атрибутам с помощью отражения (C#).

Если вы хотите получить информацию о метаданных, хранящихся в атрибуте, вам нужно сделать что-то вроде этого

Пример

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

[DomainName("MyTable")]
Public class MyClass : DomainBase
{}

...

public static class AttributeExtensions
{
    public static TValue GetAttributeValue<TAttribute, TValue>(
        this Type type, 
        Func<TAttribute, TValue> valueSelector) 
        where TAttribute : Attribute
    {
        var att = type.GetCustomAttributes(
            typeof(TAttribute), true
        ).FirstOrDefault() as TAttribute;
        if (att != null)
        {
            return valueSelector(att);
        }
        return default(TValue);
    }
}

и используйте так:

string name = typeof(MyClass).GetAttributeValue((DomainNameAttribute dna) => dna.Name);
person TheGeneral    schedule 14.03.2018
comment
Интересно, как таинственным образом обрабатываются некоторые атрибуты? например DllImportAttribute или STAThread. Имеют ли компиляторы .NET специальную поддержку для таких предопределенных атрибутов? Если да, то Есть ли какой-либо механизм, позволяющий добавить такую ​​поддержку пользовательских атрибутов? - person cse; 14.03.2018
comment
Я понимаю, что могу использовать Reflections, если мне нужно использовать, то явно. Но когда эти отражения вызываются для таких атрибутов, как DllImportAttribute или STAThread? И кто это называет? Компиляторы .NET, среда выполнения .NET или что-то еще? - person cse; 14.03.2018
comment
@cse Да, фреймворк где-то глубоко внутри. вы можете найти исходный код Microsoft для кода фреймворка. - person TheGeneral; 14.03.2018
comment
Да, есть более квалифицированные люди, которые могут сказать, однако это просто используется, как и все остальные, могут использовать атрибуты. и я сомневаюсь, что это будет особый случай. это мое предположение - person TheGeneral; 14.03.2018
comment
Но когда эти отражения вызываются для таких атрибутов, как DllImportAttribute или STAThread — они используются инфраструктурой .net, вам все равно, когда они вызываются, вам нужно только указать их для достижения определенных целей. - person Sinatr; 14.03.2018
comment
@Sinatr Мое намерение состоит в том, чтобы сделать что-то за кулисами, как в случае DllImportAttribute или STAThread. Я просто хочу понять, что .NET предоставляет специальные привилегии для встроенных аннотаций, или мы также можем сделать что-то подобное с пользовательскими аннотациями? - person cse; 14.03.2018
comment
Нет никаких закулисных атрибутов, все это просто метаданные во время выполнения. - person TheGeneral; 14.03.2018
comment
@MichaelRandall Как показано в вашем примере, заранее известно, что какой класс использует настраиваемый атрибут? Но я заранее не знаю, какие другие классы используют мой настраиваемый атрибут. Кроме того, может случиться так, что какой-то другой пользователь определил свой класс в будущем, используя пользовательский атрибут. - person cse; 14.03.2018