Gray Hat C#

#5 Gray Hat C#. Руководство для хакера по созданию и автоматизации инструментов безопасности. Анонимные методы.

Здравствуйте, дорогие друзья.

Методы, которые мы использовали до сих пор, были методами класса, но мы также можем использовать анонимные методы. Эта мощная возможность C# позволяет нам динамически передавать и назначать методы с помощью делегатов. С помощью делегата создается объект делегата, содержащий ссылку на вызываемый метод. Мы создаем этот делегат в родительском классе, а затем присваиваем ссылку делегата анонимным методам в подклассах родительского класса. Таким образом, мы можем динамически назначать делегату блок кода в подклассе, вместо переопределения метода родительского класса. Чтобы продемонстрировать, как использовать делегаты и анонимные методы, мы можем использовать уже созданные классы.


Назначение делегата методу

Давайте обновим класс PublicServant, чтобы использовать делегат для метода DriveToPlaceOfInterest(), как показано в листинге 1-9.

Listing 1-9: The PublicServant class with a delegate

В предыдущем классе PublicServant нам нужно было переопределить метод DriveToPlaceOfInterest(), если мы хотели его изменить. В новом классе, PublicServant DriveToPlaceOfInterest() заменен делегатом [1] и свойством [2], которые позволяют нам вызывать и назначать DriveToPlaceOfInterest(). Теперь любые классы, унаследованные от класса PublicServant, будут иметь делегат, который они смогут использовать для установки собственного анонимного метода для DriveToPlaceOfInterest(), вместо необходимости переопределять метод внутри каждого класса. Поскольку они наследуются от PublicServant, нам необходимо соответствующим образом обновить конструкторы классов Firefighter и PoliceOfficer.

Обновление класса пожарного


Сначала мы обновим класс Firefighter, добавив новое свойство делегата. Конструктор, показанный в листинге 1.10, — единственное изменение, которое мы вносим.

Listing 1-10: The Firefighter class using the delegate for the DriveToPlaceOfInterest() method

В новом конструкторе [1] класса Firefighter мы назначаем Name [2] Age [3], как мы это делали раньше. Затем мы создаем анонимный метод и присваиваем его свойству делегата DriveToPlaceOfInterest с помощью оператора += [4], чтобы вызов DriveToPlaceOfInterest() вызывал анонимный метод. Этот анонимный метод печатает «Driving the firetruck», а затем запускает пустые методы из исходного класса. Таким образом, мы можем добавить индивидуальный код к каждому методу внутри класса, без необходимости его переопределять.


Создание необязательных аргументов

Класс PoliceOfficer требует аналогичного изменения; мы обновляем конструктор, как показано в листинге 1-11. Поскольку мы уже обновляем этот класс, мы также можем изменить его, чтобы использовать необязательный аргумент, который является параметром конструктора, который не нужно включать при создании нового экземпляра. Мы создадим два анонимных метода и будем использовать необязательный аргумент, чтобы определить, какой метод назначить делегату.

Listing 1-11: The new PoliceOfficer constructor
Listing 1-11: The new PoliceOfficer constructor

В новом конструкторе [1] PoliceOfficer, мы установили свойства Name [3] и Age [4] так же, как и изначально. Однако на этот раз мы также используем необязательный третий аргумент [3] — для назначения свойства HasEmergency [5]. Третий аргумент является необязательным, поскольку его не нужно указывать; он имеет значение по умолчанию (false), когда конструктору предоставляются только первые два аргумента. Затем мы устанавливаем для свойства делегата DriveToPlaceOfInterest новый анонимный метод, в зависимости от того, имеет ли HasEmergency значение true [6].

Обновление метода Main()


Благодаря новым конструкторам, мы можем запустить обновленный метод Main(), который почти идентичен первому. Подробно это описано в листинге 1-12.

Listing 1-12: The updated Main() method using our classes with delegates for driving to places of interest

Единственные различия заключаются в последних трех строках, которые демонстрируют создание нового PoliceOfficer [2], у которого возникла чрезвычайная ситуация (третий аргумент конструктора true), в отличие от Jane Hope [1], у которой ее нет. Затем мы вызываем DriveToPlaceOfInterest() для офицера John Valor [3].


Запуск обновленного метода Main()

Запуск нового метода показывает, как создание двух классов PoliceOfficer — одного с экстренной ситуацией и другого без нее — выведет две разные вещи, как показано в листинге 1-13.

Listing 1-13: Running the new Main() method with classes using delegates

Как видите, создание класса PoliceOfficer с аварийной ситуацией заставляет офицера ездить с включенной сиреной [2]. Jane Hope, с другой стороны, может водить машину без сирены [1], потому что у нее нет экстренных ситуаций.

На этом все. Всем хорошего дня!

Цикл статей по Gray Hat C#. Руководство для хакера по созданию и автоматизации инструментов безопасности.