Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курс_ред.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
1.76 Mб
Скачать

Перегрузка функций

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

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

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

static int maxValue(int[] intArray)

{

int maxVal = intArray[0];

for (int i = 1; i < intArray.Length; i++)

{

if (intArray[i] > maxVal)

maxVal = intArray[i];

}

return maxVal;

}

Эта функция может использоваться только для массивов значений типа int. Мы могли бы создать функции с другими именами, предназначенные для работы с параметрами других типов, переименовав вышеприведенную функцию как-нибудь вроде IntArrayMaxValue() И добавив функции наподобие DoubleArrayMaxValue() для работы с данными с плавающей точкой. Вместо этого в качестве альтернативы мы можем просто включить в нашу программу следующую функцию:

static double maxValue(double[] doubleArray)

{

double maxVal = doubleArray[0];

for (int i = 1; i < doubleArray.Length; i++)

{

if (doubleArray[i] > maxVal)

maxVal = doubleArray[i];

}

return maxVal;

}

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

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

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

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

double result = maxValue(

Редактор Visual Studio выведет информацию по обеим версиям функции maxValue(), которые мы можем просмотреть с помощью кнопок "стрелка вверх" и "стрелка вниз":

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

static void showDouble(ref int val)

{

. . .

}

static void showDouble(int val)

{

. . .

}

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

showDouble(ref val);

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

showDouble(val);

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

static double func(int x)

{

. . .

}

static int func(int x)

{

. . .

}

При компиляции второй функции получим ошибку: в классе Program уже определена функция func() с такими же типами параметров.