Как создать пользовательский атрибут в C # - PullRequest
106 голосов
/ 02 февраля 2011

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

Может кто-нибудь объяснить мне очень простой примерпользовательский атрибут с кодом?

Ответы [ 3 ]

247 голосов
/ 02 февраля 2011

Вы начинаете с написания класса, производного от Атрибут :

public class MyCustomAttribute: Attribute
{
    public string SomeProperty { get; set; }
}

Тогда вы можете украсить что угодно (класс, метод, свойство, ...) этим атрибутом:

[MyCustomAttribute(SomeProperty = "foo bar")]
public class Foo
{

}

и, наконец, вы должны использовать отражение, чтобы получить его:

var customAttributes = (MyCustomAttribute[])typeof(Foo).GetCustomAttributes(typeof(MyCustomAttribute), true);
if (customAttributes.Length > 0)
{
    var myAttribute = customAttributes[0];
    string value = myAttribute.SomeProperty;
    // TODO: Do something with the value
}

Вы можете ограничить целевые типы, к которым можно применить этот пользовательский атрибут, используя атрибут AttributeUsage :

/// <summary>
/// This attribute can only be applied to classes
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class MyCustomAttribute : Attribute

Важные сведения об атрибутах:

  • Атрибуты являются метаданными.
  • Они запекаются в сборку в время компиляции , что очень серьезно влияет на то, как вы можете установить их свойства. Только постоянные (известные во время компиляции) значения принимаются
  • Единственный способ понять смысл и использовать пользовательские атрибуты - это использовать Reflection . Поэтому, если вы не используете отражение во время выполнения, чтобы извлечь их и украсить что-либо с помощью специального атрибута, не ожидайте, что многое произойдет.
  • Время создания атрибутов недетерминировано. Они создаются CLR, и вы абсолютно не можете их контролировать.
89 голосов
/ 02 февраля 2011

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

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

Так, например, давайте посмотрим на Блок приложения проверки , из Корпоративная библиотека . Если вы посмотрите на пример кода, вы увидите:

    /// <summary>
    /// blah blah code.
    /// </summary>
    [DataMember]
    [StringLengthValidator(8, RangeBoundaryType.Inclusive, 8, RangeBoundaryType.Inclusive, MessageTemplate = "\"{1}\" must always have \"{4}\" characters.")]
    public string Code { get; set; }

Из приведенного выше фрагмента можно догадаться, что Код всегда будет проверяться при каждом изменении в соответствии с правилами Валидатора (в данном примере они содержат не менее 8 символов и не более 8 символов). Но правда в том, что Атрибут ничего не делает, только добавляет метаданные к свойству.

Однако в Enterprise Library есть метод Validation.Validate, который будет проверять ваш объект, и для каждого свойства он будет проверять, нарушает ли содержимое правило, сообщаемое атрибутом.

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

20 голосов
/ 16 июня 2017

Использование / Копирование Отличный ответ Дарина Димитрова , это как получить доступ к пользовательскому атрибуту свойства, а не класса:

Украшенная собственность [класса Foo]:

[MyCustomAttribute(SomeProperty = "This is a custom property")]
public string MyProperty { get; set; }

Загрузка:

PropertyInfo propertyInfo = typeof(Foo).GetProperty(propertyToCheck);
object[] attribute = propertyInfo.GetCustomAttributes(typeof(MyCustomAttribute), true);
if (attribute.Length > 0)
{
    MyCustomAttribute myAttribute = (MyCustomAttribute)attribute[0];
    string propertyValue = myAttribute.SomeProperty;
}

Вы можете бросить это в цикл и использовать отражение для доступа к этому пользовательскому атрибуту в каждом свойстве класса Foo, а также:

foreach (PropertyInfo propertyInfo in Foo.GetType().GetProperties())
{
    string propertyName = propertyInfo.Name;

    object[] attribute = propertyInfo.GetCustomAttributes(typeof(MyCustomAttribute), true);
    // Just in case you have a property without this annotation
    if (attribute.Length > 0)
    {
        MyCustomAttribute myAttribute = (MyCustomAttribute)attribute[0];
        string propertyValue = myAttribute.SomeProperty;
        // TODO: whatever you need with this propertyValue
    }
}

Большое спасибо тебе, Дарин !!

...