C# → Атрибуты и создание пользовательских атрибутов

По сути дела атрибут – это маркер, которым можно пометить элемент кода, например метод или класс (или даже отдельный аргумент).

[Conditional] (рус. условный) используется для пометки метода как отладочного. Компилятор не будет компилировать этот метод (и любые операторы которые ссылаются на него), если определен следующий символ («DEBUG» например). Объявлен в System.Giagnostics.

[Conditional("DEBUG")] 
public void Generate() {  // отладка }

[DllImport] – помечает метод, как определенный во внешней DLL, а не в какой-либо сборке. Объявлен в пространстве имен System.Runtime.InteropServices.

[DllImport("user32.dll")] 
public static extern int MessageBox(int hParent, string Message, string Caption, int Type); 
...  
MessageBox(0, "Hello", "myProgram", 0);

[Obsolete(«сообщение»),false] – пометка метода, который считается устаревшим (генерируется либо предупреждение, либо ошибка компиляции).

[StructLatout] – позволяет указать точное расположение полей структуры в памяти.

Пользовательские атрибуты

Пример пользовательского атрибута:

[FieldName("SocialSecurityName")]
public string SocialSecurityNumber() { // .. }

Увидев, что метод имеет атрибут FieldName, компилятор прибавит к этому имени строку «Attribute» (только в случае ее отсутствия), образовав полное имя FieldNameAttribute, а затем будет искать во всех пространствах имен класс с тем же именем. Компилятор предположит, что существует класс с таким именем и что этот класс наследуется от System.Attribute.

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

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field, AllowMultiple=false, Inherited=false)]
public class FieldNameAttribute : Attribute
{
        private string name;
        public FieldNameAttribute(string initName) { name = initName; }
}

AttributeUsage – мета-атрибут, который служит для указания того, к каким элементам кода может быть применен атрибут. Атрибут может быть указан для сборки в целом (AttributeTargets.Assembly), при этом атрибут может быть помещен в любом месте кода, но должен быть отмечен с помощью ключевого слова: [assembly: SomeAssemblyAttribute(Parameters)]

AllowMultiple – может ли атрибут применяться более одного раза, (не обязательный).

Ingerited (рус. унаследованный) – атрибут примененный к классу или интерфейсу будет также применен ко всем унаследованным классам и интерфейсам? Если атрибут применен к методу или свойству, то он будет автоматически применен ко всем перекрытым методам или свойствам.

Принимает атрибут параметры или нет, определяется тем, какие конструкторы доступны.

Для добавления необязательных параметров («comment») можно организовать работу с помощью свойств или полей в классе атрибута. Для этого необходимо добавить свойство (pub. поле):

private string comment;
public string Comment
{
            get { return comment; }
            set { comment = value; }
}

Доступ осуществляется:

[FieldNameAttribute("SocialSecurityName", Comment="value")]