Подтвердить что ты не робот

Атрибуты в С#

Я знаю, что С# (и .NET в целом) большой по атрибутам. Однако, несмотря на то, что я программировал на С# в течение многих лет, я не обнаружил, что когда-либо использовал их. Кто-нибудь заставит меня начать с них, и объясните, где их лучше всего использовать?

Спасибо

4b9b3361

Ответ 1

От Pro С# 2008 и платформа .NET 3.5, четвертое издание от Andrew Troelsen

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

Одна из составляющих компилятора .NET - генерировать метаданные описания для всех определенных и ссылочных типов. В дополнение к этим стандартным метаданным в любой сборке платформа .NET предоставляет возможность программистам встраивать дополнительные метаданные в сборку с использованием атрибутов. Вкратце, атрибуты - это не что иное, как код аннотации, которые могут быть применены к данному типу (класс, интерфейс, структура и т.д.), член (свойство, метод и т.д.), сборку или модуль. Идея аннотирования кода с использованием атрибутов не нова. COM IDL предоставил множество предопределенных атрибуты, позволяющие разработчикам описывать типы, содержащиеся в данном COM-сервере. Однако атрибуты COM были немного больше, чем набор ключевых слов. Если разработчику COM необходимо было создать пользовательский атрибут, он или она может это сделать, но на это ссылался код в 128-битном номере (GUID), который был в лучшем случае громоздким. В отличие от атрибутов COM IDL (которые снова были просто ключевыми словами), атрибуты .NET являются типами классов которые расширяют абстрактный базовый класс System.Attribute. Когда вы исследуете пространства имен .NET, вы будете найти множество предопределенных атрибутов, которые вы можете использовать в своих приложениях. Более того, вы можете создавать пользовательские атрибуты для дальнейшего определения поведения ваших типов, создавая новый тип, полученный из атрибута. Понимать, что при применении атрибутов в коде встроенные метаданные бесполезно, пока другая часть программного обеспечения явно не отразится на информации. Если это не так, фрагмент метаданных, встроенных в сборку, игнорируется и полностью безвреден.

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

Как вы могли догадаться, SDK.NET 3.5 Framework поставляется с многочисленными утилитами, которые действительно включены поиск различных атрибутов. Сам компилятор С# (csc.exe) был предварительно запрограммирован на выявить наличие различных атрибутов во время цикла компиляции. Например, если С# компилятор встречает атрибут [CLSCompliant], он автоматически проверяет атрибут убедитесь, что он раскрывает только конструкции, совместимые с CLS. В качестве другого примера, если компилятор С# обнаруживает элемент, присваиваемый атрибутом [Устаревший], он отображает предупреждение компилятора в Окно списка ошибок Visual Studio 2008. В дополнение к инструментам разработки многочисленные методы в библиотеках базового класса .NET предварительно запрограммированы для отражения конкретных атрибутов. Например, если вы хотите сохранить состояние object to file, все, что вам нужно сделать, это аннотировать ваш класс атрибутом [Serializable]. Если метод Serialize() класса BinaryFormatter встречает этот атрибут, объект автоматически сохранялся в файле в компактном двоичном формате. .NET CLR также находится в поиске новых атрибутов. Возможно, наиболее известный атрибут .NET - это [WebMethod]. Если вы хотите разоблачить метод через HTTP-запросы и автоматически закодируйте возвращаемое значение метода как XML, просто примените [WebMethod] к методу и CLR обрабатывает детали. Помимо разработки веб-сервисов, атрибуты имеют решающее значение для система безопасности .NET, Windows Communication Foundation и совместимость с COM/.NET(и так далее). Наконец, вы можете создавать приложения, которые запрограммированы, чтобы отражать ваши собственные атрибуты, а также любой атрибут в библиотеках базового класса .NET. Поступая таким образом, вы по существу способный создавать набор "ключевых слов", которые понимаются конкретным набором сборок.

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

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

Небольшая выборка предопределенных атрибутов

[CLSCompliant]

Заставляет аннотированный элемент соответствовать правилам Common Спецификация языка (CLS). Напомним, что CLS-совместимые типы гарантированно будет использоваться на всех языках программирования .NET.

[DllImport]

Позволяет .NET-коду совершать вызовы на любой неуправляемый код на C- или С++ библиотеки, включая API базовой операционной системы. Обратите внимание, что [DllImport] не используется при общении с программным обеспечением на базе COM.

[Устаревшее]

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

[Сериализуемый]

Отмечает класс или структуру как "сериализуемую", то есть она может сохраняться его текущее состояние в поток.

[NonSerialized]

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

[WebMethod]

Отмечает метод как invokable через HTTP-запросы и инструктирует CLR для сериализации возвращаемого значения метода как XML.

Создание пользовательских атрибутов

Первым шагом в создании настраиваемого атрибута является создание нового класса, полученного из System.Attribute. Пример:

// A custom attribute.
public sealed class VehicleDescriptionAttribute : System.Attribute
{
    private string msgData;

    public VehicleDescriptionAttribute(string description)
    {
        msgData = description;
    }

    public VehicleDescriptionAttribute() { }

    public string Description
    {
        get { return msgData; }
        set { msgData = value; }
    }
}

Как вы можете видеть, VehicleDescriptionAttribute поддерживает частную внутреннюю строку (msgData) который может быть установлен с использованием пользовательского конструктора и управляться с использованием свойства type (Description). Помимо того факта, что этот класс получен из System.Attribute, нет ничего уникального для этого класса определение.

По соображениям безопасности считается наилучшей практикой .NET для проектирования всех настраиваемых атрибутов как запечатанных. В факту, Visual Studio 2008 предоставляет фрагмент кода с именем Attribute, который выведет новую систему. Атрибут-производный класс в ваше окно кода.

Ответ 2

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

Например, вы можете использовать атрибуты для импорта dll, указать, как типы будут взаимодействовать с визуальной студией (видимость дизайнера, подсказка intellisense, шаг отладчика и т.д.), как их сериализовать, указать тип устарел, описать значения по умолчанию, описания, обрабатывать COM-доступ и т.д.

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

Ответ 3

Мне нравится использовать атрибуты в качестве метаданных для моего кода. Мы создали несколько простых атрибутов, которые позволяют нам пометить, кто написал код, когда и почему. Это позволяет нам документировать изменения кода и во время выполнения. Если во время выполнения есть исключения, мы можем проверить столбец, посмотреть на какие-либо атрибуты методов на этом пути и отследить ответственных лиц:

[Author("Erich", "2009/04/06", Comment = "blah blah blah")]
public void MyFunction()
{
...
}

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

Ответ 4

Атрибуты - это форма декларативного программирования, "похожее" на создание вашего пользовательского интерфейса в XAML. Он "маркирует" фрагменты кода (классы, методы, свойства и т.д.) С атрибутом, чтобы впоследствии можно было собрать все те части, отмеченные определенным образом, а затем сделать что-то стандартное со всеми из них.

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

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

Ответ 5

Я полагаю, вы подразумеваете, что вы не используете (или часто используете) настраиваемые атрибуты?

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

Это инструмент/цель, чтобы перейти к заданному решению.

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

В моем текущем проекте я также использую атрибуты для украшения определенных типов с дополнительной информацией... Но я считаю, что я опубликовал об этом здесь раньше: Прохладное использование атрибутов или аннотаций (CLR или Java)?

Ответ 6

Я использую атрибуты для следующего:

  • Связь с архитектурой подключаемого модуля
  • Рассказывать другую структуру, что делать с кодом (например, NUnit)
  • Добавление метаданных для использования с другим кодом (см. PropertyGrid)
  • Сопоставление объектов с базами данных (см. Замок ActiveRecord)
  • При написании моих собственных API-интерфейсов, позволяющих пользователям передавать метаданные
  • В коде рамки, чтобы сообщить отладчику пропустить его

Те, кто не в моей голове. Я использую их во многих других местах.

Ответ 7

Атрибуты очень хороши при описании поведения во время выполнения вашего кода, который является ортогональным к рассматриваемому коду. Например, в классе Customer, который вы бы моделировали клиента, не так ли? Но вы, возможно, не захотите моделировать или описывать, как объект Customer сериализуется.

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

MSTest и NUnit используют атрибуты, чтобы сообщить платформе тестирования, как следует использовать классы, которые определяют тестовые приборы.

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

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

Ответ 8

Определение атрибута класса доступно здесь

ClassInterfaceAttribute: Указывает тип интерфейса класса, который будет создан для класса, открытого для COM, если интерфейс генерируется вообще.

ComDefaultInterfaceAttribute: Указывает интерфейс по умолчанию для отображения на COM. Этот класс нельзя унаследовать.

ComVisibleAttribute: управляет доступом к отдельному управляемому типу или члену или всем типам сборки в COM.