Как создать пользовательский атрибут в C#

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

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

3 ответов


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

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

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

    /// <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 символов). Но правда в том, что атрибут ничего не делает, только добавляет метаданные к свойству.

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

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


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

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

важные вещи, чтобы знать о атрибуты:

  • атрибуты метаданных.
  • они запекаются в сборке в времени компиляции что имеет очень серьезные последствия того, как вы могли бы установить свои свойства. Принимаются только постоянные (известные во время компиляции) значения
  • единственный способ сделать какой-либо смысл и использование пользовательских атрибутов-использовать отражение. Поэтому, если вы не используете отражение во время выполнения, чтобы получить их и украсить что-то пользовательским атрибут не ожидает многого.
  • время создания атрибутов является недетерминированным. Они создаются CLR, и у вас нет абсолютно никакого контроля над ним.

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

украшенное свойство [класса 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
    }
}

майор благодаря вам, Дарин!!