Litvek: лучшие книги недели
Топ книга - Лавр [Евгений Германович Водолазкин] - читаем полностью в LitvekТоп книга - Сила воли. Как развить и укрепить [Келли Макгонигал] - читаем полностью в LitvekТоп книга - Под тенью Сатурна [Джеймс Холлис] - читаем полностью в Litvek
Litvek - онлайн библиотека >> Алекс Jenter >> C, C++, C# и др. >> Программирование на Visual C++. Архив рассылки >> страница 193
Теперь настало время рассмотреть механизм получения атрибутов, ведь мало научиться сохранять свои атрибуты в метаданных, важно еще и уметь получать и использовать их. К счастью, получение пользовательского атрибута – простая задача. Сначала объявляется переменная с типом атрибута, который нужно получить, затем она инициализируется с помощью вызова метода Attribute.GetCustomAttribute. Все, теперь можно использовать любые доступные свойства атрибута.

Получение одиночного атрибута
В следующем примере атрибут DeveloperAttribute (рассмотренный выше) применяется к классу MainApp в целом. Метод GetAttribute использует Attribyte.GetCustomAttribute для получения состояния атрибута DeveloperAttribute перед тем, как вывести информацию на консоль.

C#

using System;

[Developer("Иван Семенов", "42", Reviewed = true)]

class MainApp {

 public static void Main() {

  // Вызвать функцию получения и отображения атрибута.

  GetAttribute(typeof(MainApp));

 }

 public static void GetAttribute(Type t) {

  // Получить атрибут.

  DeveloperAttribute MyAttribute =

   (DeveloperAttribute)Attribute.GetCustomAttribute(t, typeof(DeveloperAttribute));

  if (MyAttribute == null) {

   Console.WriteLine("Атрибут не найден.");

  } else {

   // Получить поле Имя.

   Console.WriteLine("Имя: {0}." , MyAttribute.Name);

   // Получить поле Уровень.

   Console.WriteLine("Уровень: {0}." , MyAttribute.Level);

   // Получить поле Проверено.

   Console.WriteLine("Проверено: {0}." , MyAttribute.Reviewed);

  }

 }

}

MC++

#using <mscorlib.dll> using namespace System;

[Developer(S"Иван Семенов", S"42", Reviewed = true)]

public__gc class MainApp{

public:

 static void GetAttribute(Type* t) {

  // Получить атрибут.

  DeveloperAttribute* MyAttribute =

   __try_cast<DeveloperAttribute*>

   (Attribute::GetCustomAttribute(t, __typeof(DeveloperAttribute)));

  if (MyAttribute == 0)

   Console::WriteLine(S"Атрибут не найден.");

  else {

   // Получить поле Имя.

   Console::WriteLine(S"Имя: {0}." , MyAttribute->Name);

   // Получить поле Уровень.

   Console::WriteLine(S"Уровень: {0}." , MyAttribute->Level);

   // Получить поле Проверено.

   Console::WriteLine(S"Проверено: {0}." , MyAttribute->Reviewed);

  }

 }

};


void main() {

 // Вызвать функцию получения и отображения атрибута.

 MainApp::GetAttribute(__typeof(MainApp));

}

Visual Basic.NET

Imports System

Class <Developer("Иван Семенов", "42", Reviewed := True)> MainApp

 Public Shared Sub Main()

  ' Вызвать функцию получения и отображения атрибута.

  GetAttribute(GetType(MainApp))

 End Sub


 Public Shared Sub GetAttribute(t As Type) ' Получить атрибут.

  Dim MyAttribute As DeveloperAttribute = _

   CType(Attribute.GetCustomAttribute(t, GetType(DeveloperAttribute)), DeveloperAttribute)

  If MyAttribute Is Nothing Then Console.WriteLine("Атрибут не найден.")

  Else ' Получить поле Имя.

   Console.WriteLine("Имя: {0}.", MyAttribute.Name) ' Получить поле Уровень.

   Console.WriteLine("Уровень: {0}.", MyAttribute.Level) ' Получить поле Проверено.

   Console.WriteLine("Проверено: {0}.", MyAttribute.Reviewed)

  End If

 End Sub

End Class

При запуске эта программа выдает на консоль следующие строки:

Имя: Иван Семенов

Уровень: 42

Проверено: True

Если атрибут не найден, метод GetCustomAttribute возвращает нулевое значение. В этом примере предполагается, что атрибут определен в текущем пространстве имен, если это не так, не забудьте импортировать соответствующее пространство имен.

Получение списка однотипных атрибутов
В предыдущем примере ссылки на класс и атрибут передавались в метод GetCustomAttribute. Этот код прекрасно работает, если на уровне класса определен только один атрибут. Но если на том же уровне определено несколько однотипных атрибутов, этот метод вернет не всю информацию. В таких случаях нужно использовать метод Attribute.GetCustomAttributes, который возвращает массив атрибутов. Например, если на уровне класса определены два экземпляра атрибута DeveloperAttribute, можно модифицировать метод GetAttribute, чтобы получить оба.

Как это сделать, показано в следующем примере:

C#

public static void GetAttribute(Type t) {

 // Получить атрибут.

 DeveloperAttribute[] MyAttribute =

  (DeveloperAttribute[]) Attribute.GetCustomAttributes(t, typeof(DeveloperAttribute));

 if (MyAttribute == null) Console.WriteLine("Атрибут не найден.");

 else for (int i = 0; i < MyAttribute.Length; i++) {

  // Получить поле Имя.

  Console.WriteLine("Имя: {0}." , MyAttribute[i].Name);

  // Получить поле Уровень.

  Console.WriteLine("Уровень: {0}." , MyAttribute[i].Level);

  // Получить поле Проверено.

  Console.WriteLine("Проверено: {0}.", MyAttribute[i].Reviewed);

 }

}

MC++

public:

 static void GetAttribute(Type* t) {

  // Получить атрибут.

  DeveloperAttribute* MyAttribute __gc[] =

   __try_cast<DeveloperAttribute* __gc[]>(Attribute::GetCustomAttributes(t, __typeof(DeveloperAttribute)));

  if (MyAttribute == 0) Console::WriteLine(S"Атрибут не найден.");

  else for (int i = 0; i < MyAttribute.Length; i++) {

   // Получить поле Имя.

   Console::WriteLine(S"Имя: {0}." , MyAttribute[i]->Name);

   // Получить поле Уровень.

   Console::WriteLine(S"Уровень: {0}." , MyAttribute[i]->Level);

   // Получить поле Проверено.

   Console::WriteLine(S"Проверено: {0}." , MyAttribute[i]->Reviewed);

  }

 }

Visual Basic.NET

Public Shared Sub GetAttribute(t As Type)

 ' Получить атрибут.

 Dim MyAttribute As DeveloperAttribute() = _

  CType(Attribute.GetCustomAttributes(t, GetType(DeveloperAttribute)), DeveloperAttribute())

 If MyAttribute Is Nothing Then

  Console.WriteLine("Атрибут не найден.")

 Else

  Dim i As Integer

  For i = 0 To MyAttribute.Length – 1 ' Получить поле Имя.

   Console.WriteLine("Имя: {0}.", MyAttribute(i).Name)

   ' Получить поле Уровень.

   Console.WriteLine("Уровень: {0}.", MyAttribute(i).Level)

   ' Получить поле Проверено.

   Console.WriteLine("Проверено: {0}.", MyAttribute(i).Reviewed)

  Next i

 End If

End Sub

Получение списка разнотипных атрибутов
Методы GetCustomAttribute и GetCustomAttributes не могут искать атрибут во всем классе и возвращать все его экземпляры. Они просматривают только один метод или поле за раз. Поэтому, если есть класс с одним атрибутом для всех методов и нужно получить все экземпляры этого атрибута, не остается ничего делать, как передавать эти методы один за другим в качестве параметров GetCustomAttribute и GetCustomAttributes.

В следующем фрагменте кода показано, как получить все экземпляры атрибута DeveloperAttribute, определенного как на уровне класса, так и на уровне методов.

C#

using System;

using System.Reflection;

public static void GetAttribute(Type t) {

 // Получить атрибут уровня класса.

 DeveloperAttribute att =

  (DeveloperAttribute) Attribute.GetCustomAttribute (t, typeof(DeveloperAttribute));

 if (att == null)

  Console.WriteLine("Класс {0} не имеет атрибута Developer.\n", t.ToString());

 else {

  Console.WriteLine("Атрибут Имя на уровне класса: {0}.", att.Name);

  Console.WriteLine("Атрибут Уровень на уровне класса: {0}.", att.Level);

  Console.WriteLine("Атрибут Проверено на уровне класса: {0}.\n", att.Reviewed);

 }

 // Получить атрибуты уровня методов.

 // Получить все методы данного класса и поместить их

 // в массив объектов System.Reflection.MemberInfo.

 MemberInfo[] MyMemberInfo = t.GetMethods();

 // Вывести атрибуты всех методов класса

 for (int i = 0; i < MyMemberInfo.Length; i++) {

  att =

   (DeveloperAttribute)Attribute.GetCustomAttribute(MyMemberInfo[i], typeof (DeveloperAttribute));

  if (att == null)

   Console.WriteLine("Метод {0} не имеет атрибута Developer.\n" ,

    MyMemberInfo[i].ToString());

  else {

 
Litvek: лучшие книги месяца
Топ книга - Этюды черни [Ольга Анатолиевна Ускова] - читаем полностью в LitvekТоп книга - Секрет Сибирского Старца [Юлия Ефимова] - читаем полностью в LitvekТоп книга - Грани Власти (СИ) [Роман Осадчук] - читаем полностью в Litvek