Делегаты

. . .

. . .

. . .

Разница между двумя функциями заключается в том, что эта функция работает со значениями типа double. Имя функции — MaxValue() — оказывается тем же самым, однако сигнатура (это принципиально) отличается. Было бы ошибкой описать две функции с одинаковым именем и одинаковой сигнатурой, однако поскольку в данном случае сигнатуры различны, то все нормально.

Теперь у нас имеются две версии функции MaxValue (), которые принимают массивы типа int и массивы типа double и возвращают максимальное значение типа int или типа double соответственно. Красота такой формы программы в том, что не требуется явно указывать, которую из этих двух функций мы собираемся использовать. Мы просто задаем массив-параметр, и это приводит к выполнению того варианта, который соответствует типу используемого параметра.

На данном этапе стоит отметить еще одну высокоинтеллектуальную черту VS. Если в нашем приложении имеются две одноименные функции, описанные выше, и мы наберем это имя, например, в Main(), то VS выведет доступные варианты перегрузки данной функции. Если будет набрано следующее:

double result = MaxValue()

то VS выведет информацию по обеим версиям функции MaxValue(), которые мы можем про смотреть с помощью кнопок "стрелка вверх" и "стрелка вниз".

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

static void showDouble(ref int val)

{

}

static void showDouble(int val)

{

}

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

showDouble(ref val) ;

А такой вызов позволит передать параметр по значению:

showDouble(val);

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

Делегатомназывается тип, который позволяет хранить ссылки на функции. Объявление делегатов во многом напоминает объявление функций; при этом отсутствует само тело функции, но добавляется ключевое слово delegate. Объявление делегата определяет сигнатуру функции, состоящую из возвращаемого типа и списка параметров. После объявления делегата мы получаем возможность объявить переменную типа этого делегата. Мы можем затем инициализировать эту переменную, присвоив ей ссылку на произвольную функцию, обладающую сигнатурой, совпадающей с сигнатурой делегата. После всего этого мы получаем возможность вызывать эту самую функцию с помощью данной переменной-делегата так, как если бы последняя сама являлась этой функцией.

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