Основы C# Урок 32. Делегаты
Сначала пара слов о том, что такое делегаты. В языке
программирования могут быть переменные, содержащие значения
целого или вещественного типов. С такими типами все вы хорошо
знакомы. Так вот, в первом приближении делегаты - это тоже
некоторый тип данных. Что же за тип может хранится в
делегатах? В делегатах могут хранится функции (вернее
указатели на функции). Т. е. переменной типа делегат можно
сначала присвоить одну функцию, поработать с ней, а затем
присвоить другую функцию. Это все в первом приближении. Теперь
несколько подробностей. Во-первых, делегаты бывают разных
типов. Тип делегата определяется типов и количеством параметов
и типом возвращаемого значения. Это значит, что если,
например, делегат типа void и у него только один параметр типа
int, то в такой делегат мы можем записать только функцию типа
void и с одним единственым параметроам типа int. Во-вторых,
делегаты, в отличие от указателей на функции языка C++,
предаставляют из себя безопасные типы данных.
Вот пример делегата: using System;
namespace test
{
//Объявление делегата.
delegate float MyFunc(float x);
//Класс для тестирования делегата.
class Test
{
//Первая функция.
static float f1(float x)
{
return x;
}
//Вторая функция.
static float f2(float x)
{
return x*x;
}
//Третья функция.
static float f3(float x)
{
return (float)Math.Sqrt(x);
}
//Метод Main.
static void Main()
{
//Создаем экземпляр делегата.
MyFunc f = new MyFunc(f1);
int a; //Ответ пользователя.
Console.WriteLine("Выберите функцию:\n1.f1=x.\n2.f2=x*x.\n3.f3=sqrt(x).");
//Преобразуем ответ пользователя к типу Int32
a=Int32.Parse(Console.ReadLine());
switch(a)
{
case 1:
//Записываем в делегат 1-ю функцию.
f=new MyFunc(f1);
break;
case 2:
//Записываем в делегат 2-ю функцию.
f=new MyFunc(f2);
break;
case 3:
//Записываем в делегат 3-ю функцию.
f=new MyFunc(f3);
break;
}
//Печатаем результат.
int x=4;
Console.WriteLine("f({0})={1}", x, f(x));
}
}
}
В этой программе мы сначала объявляем делегат: ...
delegate float MyFunc(float x);
...
Синаксис объявления делегата такой - сначала пишем ключевое
слово delegate, затем - тип возвращаемого значения (float в
нашем примере), потом - произвольное имя делегата (у нас это
MyFunc), после которого в круглых скобках перечисляем
параметры (у нас только один параметр типа float). Объявленный
делегат появится на вкладке ClassView (со специальным значком
для делегатов):
Далее мы в нашем тестовом классе объявляем несколько
методов - f1, f2 и f3. Все эти методы имеют тип float и один
параметр типа float (как и у делегата MyFunc). Функции делают
свой подсчет по-разному - первая просто возвращает параметр,
вторая - квадрат параметра, третья - корень из параметра.
Далее мы в методе Main создаем экземпляр нашего делегата и
в зависимости от ответа пользователя записываем в него f1, f2
или f3. Потом в строке ...
Console.WriteLine("f({0})={1}", x, f(x));
...
мы выводим значение делегата при некотором x (равном 4 в
нашем примере). Вернее сказать, мы выводим не значение
делегата, а значение функции, которую мы записали в
делегат.
В зависимости от ответа пользователя в делегат запишется
тот или иной вариант функции и программа выведет сам x (4), x
умножить на x (16) или корень из x (2):
|