Часто бывает удобно, чтобы методы, реализующие один и тот же алгоритм для различных типов данных, имели одно и то же имя. Если имя метода является осмысленным и несет нужную информацию, это делает программу более по-нятной, поскольку для каждого действия требуется помнить только одно имя. Использование нескольких методов с одним и тем же именем, но различными типами параметров называется перегрузкой методов.
ПРИМЕЧАНИЕ
Мы уже использовали перегруженные версии методов стандартных классов и даже сами создавали перегруженные методы, когда описывали в классе несколько конструкторов.
Компилятор определяет, какой именно метод требуется вызвать, по типу фактических параметров. Этот процесс называется разрешением (resolution) перегрузки. Тип возвращаемого методом значения в разрешении не участвует1. Механизм разрешения основан на достаточно сложном наборе правил, смысл которых сводится к тому, чтобы использовать метод с наиболее подходящими аргументами И выдать сообщение, если такой не найдется. Допустим, имеется четыре варианта метода, определяющего наибольшее значение:
Если последний параметр метода имеет модификатор params, о котором рассказывается далее в этой главе, этот параметр также не учитывается.
// Возвращает наибольшее из двух целых:
int max(int a, int b)
// Возвращает наибольшее из трех целых:
int max(int a, int b, int с)
// Возвращает наибольшее из первого параметра и длины второго:
int max (int a, string b)
// Возвращает наибольшее из второго параметра и длины первого:
int max (string b, int a)
Console.WriteLine(max(1. 2));
Console.WriteLine(max(1, 2. 3)):
Console.WriteLine(max(1, "2"));
Console.WriteLine(max("1", 2));
При вызове метода max компилятор выбирает вариант метода, соответствующий типу передаваемых в метод аргументов (в приведенном примере будут последовательно вызваны все четыре варианта метода).
Если точного соответствия не найдено, выполняются неявные преобразования типов в соответствии с общими правилами, например, bool и char в int, float в double и т. п. Если преобразование невозможно, выдается сообщение об ошибке. Если соответствие на одном и том же этапе может быть получено более чем одним способом, выбирается «лучший» из вариантов, то есть вариант, содержащий меньшие количество и длину преобразований в соответствии с правилами, описанными в разделе «Преобразования встроенных арифметических типов-значений» (см. с. 45). Если существует несколько вариантов, из которых невозможно выбрать лучший, выдается сообщение об ошибке.
Вам уже известно, что все методы класса должны различаться сигнатурами. Это понятие было введено в разделе «Методы» (см. с. 106). Перегруженные методы имеют одно имя, но должны различаться параметрами, точнее, их типами и способами передачи (out или ref). Например, методы, заголовки которых приведены ниже, имеют различные сигнатуры и считаются перегруженными:
int max(int a, int b) int max(int a, ref int b)
Перегрузка методов является проявлением полиморфизма, одного из основных свойств ООП. Программисту гораздо удобнее помнить одно имя метода и использовать его для работы с различными типами данных, а решение о том, какой вариант метода вызвать, возложить на компилятор. Этот принцип широко используется в классах библиотеки.NET. Например, в стандартном классе Console метод WriteLine перегружен 19 раз для вывода величин разных типов.