Что такое атрибуты in.NET?


Что такое атрибуты в .NET, для чего они хороши, и как я могу создать свои собственные атрибуты?

11 198

11 ответов:

метаданные. Данные о ваших объектах / методах / свойствах.

например, я могу объявить атрибут с именем: DisplayOrder, чтобы я мог легко контролировать, в каком порядке свойства должны отображаться в пользовательском интерфейсе. Затем я мог бы добавить его в класс и написать некоторые компоненты GUI, которые извлекают атрибуты и упорядочивают элементы пользовательского интерфейса соответствующим образом.

public class DisplayWrapper
{
    private UnderlyingClass underlyingObject;

    public DisplayWrapper(UnderlyingClass u)
    {
        underlyingObject = u;
    }

    [DisplayOrder(1)]
    public int SomeInt
    {
        get
        {
            return underlyingObject .SomeInt;
        }
    }

    [DisplayOrder(2)]
    public DateTime SomeDate
    {
        get
        {
            return underlyingObject .SomeDate;
        }
    }
}

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

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

[Browsable(false)]
public SomeCustomType DontShowThisInTheDesigner
{
    get{/*do something*/}
}

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

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

public void SomeProfilingMethod(MethodInfo targetMethod, object target, params object[] args)
{
    bool time = true;
    foreach (Attribute a in target.GetCustomAttributes())
    {
        if (a.GetType() is NoTimingAttribute)
        {
            time = false;
            break;
        }
    }
    if (time)
    {
        StopWatch stopWatch = new StopWatch();
        stopWatch.Start();
        targetMethod.Invoke(target, args);
        stopWatch.Stop();
        HandleTimingOutput(targetMethod, stopWatch.Duration);
    }
    else
    {
        targetMethod.Invoke(target, args);
    }
}

объявление их легко, просто сделать класс, который наследует от атрибута.

public class DisplayOrderAttribute : Attribute
{
    private int order;

    public DisplayOrderAttribute(int order)
    {
        this.order = order;
    }

    public int Order
    {
        get { return order; }
    }
}

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

многие люди ответили, но никто не упомянул об этом до сих пор...

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

Это очень полезным пометка пользовательских атрибутов какsealed классы для повышения их производительности во время выполнения.

Это также хорошая идея, чтобы рассмотреть, где это будет уместно использование такого атрибута, и атрибут атрибут (!) чтобы указать это через AttributeUsage. Список доступных атрибутов может вас удивить:

  • сборка
  • модуль
  • класс
  • Struct
  • перечисление
  • конструктор
  • метод
  • свойства
  • поле
  • событие
  • интерфейс
  • параметр
  • делегат
  • ReturnValue
  • GenericParameter
  • все

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

[AttributeUsageAttribute(AttributeTargets.Class, Inherited = true)]
public sealed class AttributeUsageAttribute : Attribute

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

начните с создания атрибутов:

[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
public class SortOrderAttribute : Attribute
{
    public int SortOrder { get; set; }

    public SortOrderAttribute(int sortOrder)
    {
        this.SortOrder = sortOrder;
    }
}

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

[SortOrder(23)]
public class MyClass
{
    public MyClass()
    {
    }
}

теперь вы можете проверить определенный класс'SortOrderAttribute (если он есть) следующим образом:

public class MyInvestigatorClass
{
    public void InvestigateTheAttribute()
    {
        // Get the type object for the class that is using
        // the attribute.
        Type type = typeof(MyClass);

        // Get all custom attributes for the type.
        object[] attributes = type.GetCustomAttributes(
            typeof(SortOrderAttribute), true);

        // Now let's make sure that we got at least one attribute.
        if (attributes != null && attributes.Length > 0)
        {
            // Get the first attribute in the list of custom attributes
            // that is of the type "SortOrderAttribute". This should only
            // be one since we said "AllowMultiple=false".
            SortOrderAttribute attribute = 
                attributes[0] as SortOrderAttribute;

            // Now we can get the sort order for the class "MyClass".
            int sortOrder = attribute.SortOrder;
        }
    }
}

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

атрибут class, который содержит немного функций, которые можно применить к объектам в коде. Создать, создать класс, который наследует от System.Атрибут.

а для чего они хороши... есть почти безграничное использование для них.

http://www.codeproject.com/KB/cs/dotnetattributes.aspx

атрибуты подобны метаданным, применяемым к классам, методам или сборкам.

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

создание собственных пользовательских из них легко, как пирог. Начните здесь:

http://msdn.microsoft.com/en-us/library/sw480ze8 (VS. 71). aspx

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

[AttributeUsage (AttributeTargets::Class)]
public ref class ControlDescriptionAttribute : Attribute
{
public:
  ControlDescriptionAttribute (String ^name, String ^description) :
    _name (name),
    _description (description)
  {
  }

  property String ^Name
  {
    String ^get () { return _name; }
  }

  property String ^Description
  {
    String ^get () { return _description; }
  }

private:
  String
    ^ _name,
    ^ _description;
};

и я применяю его к классу, как это:

[ControlDescription ("Pie Chart", "Displays a pie chart")]
public ref class PieControl sealed : UserControl
{
  // stuff
};

что предыдущие плакаты сказали.

чтобы использовать атрибут, редактор имеет Generic::List <Type> содержит типы элементов управления. Есть список, который пользователь может перетащить и падение на страницу, чтобы создать экземпляр элемента управления. Чтобы заполнить список, я получаю ControlDescriptionAttribute для управления и заполнить запись в список:

// done for each control type
array <Object ^>
  // get all the custom attributes
  ^attributes = controltype->GetCustomAttributes (true);

Type
  // this is the one we're interested in
  ^attributetype = ECMMainPageDisplay::ControlDescriptionAttribute::typeid;

// iterate over the custom attributes
for each (Object ^attribute in attributes)
{
  if (attributetype->IsInstanceOfType (attribute))
  {
    ECMMainPageDisplay::ControlDescriptionAttribute
      ^description = safe_cast <ECMMainPageDisplay::ControlDescriptionAttribute ^> (attribute);

    // get the name and description and create an entry in the list
    ListViewItem
      ^item = gcnew ListViewItem (description->Name);

    item->Tag = controltype->Name;
    item->SubItems->Add (description->Description);

    mcontrols->Items->Add (item);
    break;
  }
}

Примечание: выше C++ / CLI, но это не трудно преобразовать в C# (да, я знаю, C++ / CLI-это мерзость, но это то, с чем я должен работать : - ()

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

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

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

использование атрибутов и знание соответствующих сценариев их использования составляет основную часть работы.

атрибуты-это, по сути, биты данных, которые вы хотите прикрепить к своему типы (классы, методы, события, перечисления и т. д.)

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

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

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

вы можете использовать пользовательские атрибуты как простой способ определения значений тегов в подклассах без необходимости писать один и тот же код снова и снова для каждого подкласса. Я наткнулся на хороший краткий пример Джона Уотерса Как определить и использовать пользовательские атрибуты в свой собственный код.

есть учебник в http://msdn.microsoft.com/en-us/library/aa288454(против.71).аспн

чтобы начать создание атрибута, откройте исходный файл C#, введите attribute и нажмите [TAB]. Он будет расширен до шаблона для нового атрибута.

атрибуты также обычно используются для аспектно-ориентированного программирования. Для примера этого проверьте PostSharp.