Как создать пользовательский атрибут в 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
}
}
майор благодаря вам, Дарин!!