Атрибуты свойств С#

Я видел следующий код:

[DefaultValue(100)]
[Description("Some descriptive field here")]
public int MyProperty{...} 

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

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

Ответы

Ответ 1

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

Чтобы добавить свою специальную обработку, вы можете использовать PostSharp; существует множество отличных примеров использования PostSharp для выполнения AOP-операций, таких как ведение журнала или просто упрощение кода, например автоматическая реализация INotifyPropertyChanged.

Ответ 2

Функциональность, указанная выше snippit кажется достаточно ясным,

Возможно, нет, так как многие думают, что [DefaultValue()] задает значение свойства. Фактически, все, что он делает, чтобы рассказать о каком-то визуальном дизайнере (например, Visual Studio), о том, какой код будет устанавливать значение по умолчанию. Таким образом, он знает жирный значение в окне свойств, если оно установлено на что-то еще.

Ответ 3

Те, что в вашем примере используются визуальным дизайнером (т.е. MS Expression Blend и дизайнером Visual Studio), дают подсказки в пользовательском интерфейсе дизайнера.

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

Если вы по какой-то причине хотите получить доступ к этим атрибутам, вы должны использовать отражение.

Подробнее о атрибутах конструктора см. MSDN.

Ответ 4

Они называются атрибутами, в msdn имеется много информации, например. http://msdn.microsoft.com/en-us/library/z0w1kczw.aspx

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

Ответ 5

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

То есть у нас есть своего рода конструктор рабочих процессов, который загружает всю возможную команду типы из сборки. Эти типы команд имеют свойства, которые необходимо настроить, поэтому каждый тип команды нуждается в другом дизайнере (usercontrol).

Например, рассмотрим следующий тип команды (называемый композитом в нашем решении)

[CompositeMetaData("Delay","Sets the delay between commands",1)]
[CompositeDesigner(typeof(DelayCompositeDesigner))]
public class DelayComposite : CompositeBase 
{
       // code here
}

Эта информация используется в двух местах

1) Когда конструктор создает список команд, он использует CompositeMetaData  для отображения дополнительной информации о команде.

2) Когда пользователь добавляет команду дизайнеру, а дизайнер создает  экземпляр этого класса, он смотрит на свойство CompositeDesigner,  создает новый экземпляр указанного типа (usercontrol) и добавляет его  для визуального дизайнера.

Рассмотрим следующий код, который мы используем для загрузки команд в нашу "панель инструментов":

foreach (Type t in assembly.GetExportedTypes())  
{
    Console.WriteLine(t.Name);

    if (t.Name.EndsWith("Composite"))
    {
        var attributes = t.GetCustomAttributes(false);
        ToolboxListItem item = new ToolboxListItem();

        CompositeMetaDataAttribute meta = (CompositeMetaDataAttribute)attributes
                              .Where(a => a.GetType() == typeof(Vialis.LightLink.Attributes.CompositeMetaDataAttribute)).First();
        item.Name = meta.DisplayName;
        item.Description = meta.Description;
        item.Length = meta.Length;
        item.CompositType = t;

        this.lstCommands.Items.Add(item);
    }                           
}

Как вы можете видеть, для каждого типа сборки, имя которого заканчивается на "Composite", мы получаем пользовательские атрибуты и используем эту информацию для заполнения нашего экземпляра ToolboxListItem.

Как и для загрузки конструктора, атрибут удаляется следующим образом:

var designerAttribute = (CompositeDesignerAttribute)item.CompositType.GetCustomAttributes(false)
                         .Where(a => a.GetType() == typeof(CompositeDesignerAttribute)).FirstOrDefault();

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

Надеюсь, это даст вам место для начала.