Знакомство с делегатами в C# (Часть 1)
Делегаты в C# (теория)
Доброго времени суток! В этой статье я хочу рассказать о том, что такое делегаты в C#, как их создавать и как ими пользоваться. Делегат — это сущность в программе, которая хранит ссылку на какой-либо метод, и при необходимости, может этот метод вызвать. Сразу же может возникнуть вопрос, а зачем вызывать метод через какого-то посредника, если можно вызвать его напрямую? Дело в том, что на этапе сборки программы, программист может не знать какой метод нужно будет вызвать в определенный момент выполнения программы. А использование делегатов, как раз позволяет написать, в какой-то степени, абстрактный код. Но об этом я расскажу в следующей статье, в которой покажу пример использования делегатов на практике. А пока просто поверьте мне на слово.
Ну давайте уже разберемся как создаются делегаты. Для создания делегата, нужно сначала определить его тип. Как и в случае классов, мы создаем некий шаблон, в соответствии с которым, буде в дальнейшем создавать конкретные экземпляры. Тип делегата определяется по следующему правилу:
delegate тип_значения ИмяТипаДелегата(список_параметров);
Как видите, объявление типа делегата, отчасти, похоже на объявление метода, но в самом начале, указывается ключевое слово delegate, а после списка аргументов, нет тела как у метода, вместо которого ставит символ «;».
Обратите внимание, объект-делегат может ссылаться только на такие методы, чья сигнатура (список параметров и тип возвращаемого значения, в данном контексте) полностью совпадает с объявлением типа этого делегата. Но ссылаться делегат может как на статические, так и на обычные методы классов.
Давайте рассмотрим на практике пример объявления типа делегата и создание конкретного экземпляра данного типа:
//Объявляем делегат, по сути - тип делегатов delegate double DoubleDelegat(double aFirstArg, double aSecondArg); //Основной класс программы class Program { //Статический метод, возвращающий сумму двух аргументов static double Sum(double aFirstSumArg, double aSecondSumArg) { return aFirstSumArg + aSecondSumArg; } //Главный метод программы (точка входа) static void Main(string[] args) { //Создаем экземпляр делегата DoubleDelegat (ссылающийся на метод Sum) DoubleDelegat sumDelegat = new DoubleDelegat(Sum); } }
Как видите, создание делегата очень похоже на создание обычного объекта, но при создании объекта-делегата, мы указываем метод, на который ссылается делегат. В данном случае, это метод «Sum». А вызвать это метод через созданный делегат можно так:
//Вызов метода Sum через делегат sumDelegat double sumResult = sumDelegat(24.5, 21.4);
В примере выше, мы вызвали метод «Sum», через делегат «sumDelegat», с параметрами «24.5» и «21.4». А ниже представлен пример, в котором создаются два объекта-делегата типа «DoubleDelegat», причем один выполняет метод сложения аргументов, а второй вычитания, хотя оба имеют один тип (но ссылаются на разные методы):
//Объявляем делегат, по сути - тип делегатов delegate double DoubleDelegat(double aFirstArg, double aSecondArg); //Основной класс программы class Program { //Статический метод, возвращающий сумму двух аргументов static double Sum(double aFirstSumArg, double aSecondSumArg) { return aFirstSumArg + aSecondSumArg; } //Статический метод, возвращающий разность двух аргументов static double Sub(double aFirstSumArg, double aSecondSumArg) { return aFirstSumArg - aSecondSumArg; } //Главный метод программы (точка входа) static void Main(string[] args) { //Создаем экземпляр делегата DoubleDelegat (ссылающийся на метод Sum) DoubleDelegat sumDelegat = new DoubleDelegat(Sum); //Вызов метода Sum через делегат sumDelegat double sumResult = sumDelegat(24.5, 21.4); //Вывод результата в консоль Console.WriteLine("Результат работы sumResult с методом Sum: " + sumResult); //Создаем экземпляр делегата DoubleDelegat (ссылающийся на метод Sum) DoubleDelegat subDelegat = new DoubleDelegat(Sub); //Вызов метода Sum через делегат sumDelegat double subResult = subDelegat(24.5, 21.4); //Вывод результата в консоль Console.WriteLine("Результат работы subResult с методом Sub: " + subResult); } }
Таким образом, можно сделать вывод, что при объявлении типа делегата, мы указываем только прототип методов, которые этот делегат может вызывать, а что эти методы будут делать, мы можем даже не догадываться! И то, как этот факт мы можем использовать на практике, я расскажу в следующей статье.
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.