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 } }большое спасибо тебе, Дарин!!
Comments