Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DiVM / OSISP / ОCиСП-Часть3 / Теория / Теория (ОСиСП).doc
Скачиваний:
41
Добавлен:
11.05.2015
Размер:
616.96 Кб
Скачать

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

Атрибуты – информация, которая может быть добавлена к классу во время написания программ. Объявляется в декларативном виде, указывается в квадратных скобках.

Атрибуты – часть метаинформации, которая сохраняется в исполняемом модуле и доступна на этапе выполнения через механизм рефлексии (отражения). Гибкость .Net велика – можно использовать не только стандартные атрибуты, но и свои собственные.

Чтобы использовать атрибут (создать) надо создать класс:

public class DescriptionAttribute: Attribute

{

private string description;

public string Description {get {return description;}}

public DescriptionAttribute (string description)

{

this.description = description; }

}

}

Принято при определении своих атрибутов давать им имена такие, чтобы суффиксом было слово Attribute. Класс Attribute – базовый, должен наследовать от него.

Использование:

  1. [DescriptionAttribute (“Мой класс”)]

class MyClass{…}

  1. [Description (“Мой класс ”)]

class MyClass{…}

По соглашению компилятор пытается сначала найти с таким именем. Если не найден, компилятор добавляет суффикс Attribute и повторяет поиск. Поэтому и надо именовать классы со словом Attribute (суффикс), а там – использовать без Attribute.

[ ] – создание объекта, который укладывается в метод описаний.

Как её получить:

Type type = typeof(MyClass); // указатель на объект со всей информацией о типе

object [ ] attributes = type.GetCustomAttributes(true);

forech (object attr in attributes)

{

Console.write (“{0}”, attr.ToString( ));

DescriptionAttribute da = attr as DescriptionAttribute;

if (da != null) Console.WriteLine (“Description={0}”, da.Description);

else Console.WriteLine( );

} // foreach

GetCustomAttributes – пользовательские атрибуты. True возвращает информацию об атрибутах, включая всех предков (если MyClass наследует от кого-то).

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

[ Description («Мой класс»)]

public class MyClass

{

[ Description («Общедоступное поле»)]

public string Public Field;

[ Description («Внутреннее поле»)]

private string Private Field;

}

Как получить информацию об этих полях и их атрибутах:

Type type = typeof(MyClass);

MembersInfo[ ] members = type.GetMembers( );

forech (MembersInfo m in members) ParseAttributes (m);

static void ParseAttributes (MembersInfo type)

{

object [ ] attributes = type.GetCustimeAttributes(true);

Console.WriteLine(“{0} {1} attributes”, type.MemberType.ToString( ), type.Name);

if (attributes.Length>0)

{

foreach (object attr in attributes)

{

Console.Write (“{0}”, attr.ToString( ));

DescriptionAttribute da = attr as Description Attributes;

if (da != null) Console.WriteLine (“Description = {0}”, da.Description);

}

}

}

Данный пример иллюстрирует, как получать информацию об атрибутах, которые приписаны данному классу.

GetMembers – возвращает массив элементов с информацией об объектах (это метаинформация).

В цикле foreach вызов функции ParseAttributes, которая принимает ссылку на объект. Функция берет …, печатается имя элемента и его тип. Если в динамическом массиве есть элементы (атрибуты), то они печатаются на экран. Приводим к типу DescriptionAttributes, и, если приведение прошло успешно, печатаем.

Но работать эта программа будет не всегда. Мы получим информацию только об общедоступном поле public field, а информацию о private field не получим. Это зависит от вызова функции GetMembers( ). Чтобы получить всю информацию, надо вызывать следующий GetMembers:

MembersInfo[ ] members=type.GetMembers ( BindingFlags.Public|

BindingFlags.NonPublic|

обязательно указывать: статические BindingFlags.Static|

нестатические BindingFlags.Instance|

неунаследованные BindingFlags.DeclaredOnly);

DeclaredOnly – эти атрибуты описаны для самого класса. Т.е. если есть унаследованный класс, то всё равно, атрибуты будут выданы только данного класса, без учёта базового класса.

Атрибуты можно указывать несколько раз. Это делается следующим образом:

[ SomeAttr]

[ Description (“общедоступное поле”)] – это, если разные атрибуты

Но у одного атрибута может быть несколько свойств:

[ AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)] // (1)

public class DescriptionAttribyte : Attribute

{

private string description;

public string Description {get {return description;}}

public DescriptionAttribute (string description)

{

this.description = description;

extraInfo=” ”;

}

private string extraInfo;

public string ExtraInfo

{

get{return extraInfo}

set {extraInfo = value;}

}

}

Пример использования:

class.MyClass

{ позиционный параметр

[ Description(“Общедоступное поле”, ExtraInfo = ”оно статическое”)]

static public PublickField;

}

При описании атрибута можно использовать как позиционные, так и именованные параметры. Позиционные параметры – это параметры, передаваемые в конструктор; именованные параметры – устанавливаемые в значения свойств после конструирования атрибута.

Позиционные атрибуты следуют первыми, именованные – последними.

Компилятор по списку позиционных параметров автоматически выбирает нужный конструктор.

При создании объектов (атрибутов) надо избегать зависимости в порядке установки свойств (порядок установки свойств не должен влиять на состояние объекта).

Некоторые атрибуты бессмысленно применять к классам.

(1)атрибут, который задан в нашем CustomAttribute (т.е. это атрибут для атрибута).

AttributeTargets.All – применимо ко всему;

AllowMultiple – разрешить/запретить применение атрибута несколько раз;