Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 323 324 325 326 327 328 329 330 331 ... 642

    MethodInfo mi = miniVan.GetMethod("TurboBoost");

    // Вызвать метод (null означает отсутствие параметров).

    mi.Invoke(obj, null);

  }

  catch(Exception ex)

  {

    Console.WriteLine(ex.Message);

  }

}

Теперь после запуска приложения вы увидите в окне консоли сообщение о том, что двигатель вышел из строя ("Eek! Your engine block exploded!").

Вызов методов с параметрами

Когда позднее связывание нужно применять для вызова метода, ожидающего параметры, аргументы потребуется упаковать в слабо типизированный массив object. В версии класса Car с радиоприемником был определен следующий метод:

public void TurnOnRadio(bool musicOn, MusicMediaEnum mm)

     => MessageBox.Show(musicOn ? $"Jamming {mm}" : "Quiet time...");

Метод TurnOnRadio() принимает два параметра: булевское значение, которое указывает, должна ли быть включена музыкальная система в автомобиле, и перечисление, представляющее тип музыкального проигрывателя. Вспомните, что это перечисление определено так:

public enum MusicMediaEnum

{

  musicCd,    // 0

  musicTape,  // 1

  musicRadio, // 2

  musicMp3    // 3

}

Ниже приведен код нового метода класса Program, в котором вызывается TurnOnRadio(). Обратите внимание на использование внутренних числовых значений перечисления MusicMediaEnum:

static void InvokeMethodWithArgsUsingLateBinding(Assembly asm)

{

  try

  {

    // Получить описание метаданных для типа SportsCar.

    Type sport = asm.GetType("CarLibrary.SportsCar");

    // Создать объект типа SportsCar.

    object obj = Activator.CreateInstance(sport);

    // Вызвать метод TurnOnRadio() с аргументами.

    MethodInfo mi = sport.GetMethod("TurnOnRadio");

    mi.Invoke(obj, new object[] { true, 2 });

  }

  catch (Exception ex)

  {

    Console.WriteLine(ex.Message);

  }

}

В идеале к настоящему времени вы уже видите отношения между рефлексией, динамической загрузкой и поздним связыванием. Естественно, помимо раскрытых здесь возможностей API-интерфейс рефлексии предлагает много дополнительных средств, но вы уже должны быть в хорошей форме, чтобы погрузиться в дальнейшее изучение.

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

Вас все еще может интересовать вопрос: когда описанные приемы должны применяться в разрабатываемых приложениях? Ответ прояснится ближе к концу главы, а пока мы займемся исследованием роли атрибутов .NET Core.

Роль атрибутов .NET

Как было показано в начале главы, одной из задач компилятора .NET Core является генерация описаний метаданных для всех определяемых типов и для типов, на которые имеются ссылки. Помимо стандартных метаданных, содержащихся в любой сборке, платформа .NET Core предоставляет программистам способ встраивания в сборку дополнительных метаданных с использованием атрибутов. Выражаясь кратко, атрибуты — это всего лишь аннотации кода, которые могут применяться к заданному типу (классу, интерфейсу, структуре и т.п.), члену (свойству, методу и т.д.), сборке или модулю.

Атрибуты .NET Core представляют собой типы классов, расширяющие абстрактный базовый класс System.Attribute. По мере изучения пространств имен .NET Core вы найдете много предопределенных атрибутов, которые можно использовать в своих приложениях. Более того, вы также можете строить собственные атрибуты для дополнительного уточнения поведения своих типов путем создания нового типа, производного от Attribute.

Библиотеки базовых классов .NET Core предлагают атрибуты в различных пространствах имен. В табл. 17.3 описаны некоторые (безусловно, далеко не все) предопределенные атрибуты.

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

Потребители атрибутов

Как нетрудно догадаться, в состав .NET Core входят многочисленные утилиты, которые действительно ищут разнообразные атрибуты. Сам компилятор C# (csc.exe) запрограммирован на обнаружение различных атрибутов при проведении компиляции. Например, встретив атрибут [CLSCompilant], компилятор автоматически проверяет помеченный им элемент и удостоверяется в том, что в нем открыт доступ только к конструкциям, совместимым с CLS. Еще один пример: если компилятор обнаруживает элемент с атрибутом [Obsolete], тогда он отображает в окне Error List (Список ошибок) среды Visual Studio сообщение с предупреждением.

В дополнение к инструментам разработки многие методы в библиотеках базовых классов . NET Core изначально запрограммированы на распознавание определенных атрибутов посредством рефлексии. В главе 20 рассматривается сериализация XML и JSON, которая задействует атрибуты для управления процессом сериализации.

Наконец, можно строить приложения, способные распознавать специальные атрибуты, а также любые атрибуты из библиотек базовых классов .NET Core. По сути, тем самым создается набор "ключевых слов", которые понимает специфичное множество сборок.

Применение атрибутов в C#

Чтобы ознакомиться со способами применения атрибутов в С#, создайте новый проект консольного приложения по имени ApplyingAttributes и добавьте ссылку на System.Text.Json. Предположим, что необходимо построить класс под названием Motorcycle (мотоцикл), который может сохраняться в формате JSON. Если какое-то поле сохраняться не должно, тогда к нему следует применить атрибут [JsonIgnore].

1 ... 323 324 325 326 327 328 329 330 331 ... 642
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю бесплатно.
Похожие на Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю книги

Оставить комментарий