- •Функции
- •Определение и использование функций Определение и использование базовой функции базовой функции
- •Перегрузка функций
- •Делегаты
- •Применение делегата для вызова функции
- •Классы Определение классов в с#
- •Определение членов
- •Конструкторы и деструкторы
- •Последовательность выполнения конструкторов
- •Интерфейсы
- •Реализация интерфейсов
- •Реализация интерфейсов в классах
- •Наследование
- •Полиморфизм
- •Полиморфизм интерфейсов
Перегрузка функций
Механизм перегрузки функций (function overloading) позволяет создавать множество функций, имеющих одинаковое имя, но работающих с разными типами параметров. В коде содержится функция с именем MaxValue():
001: 002: 003: 004: 005: 006: 007 008: 009: 010: 011: 012: 013: 014: 015: 016: 017: 017 018: 019: 020:
|
class Program { 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; } static void Main(string [ ] args) { int[] myArray = {1, 8, 3, 6, 2, 5, 9, 3, 0, 2}; int maxVal = MaxValue(myArray); Console.WriteLine("The maximum value in myArray is {0}", maxVal); // Вывод максимального значения в массиве myArray Console.ReadKey(); } |
Эта функция могла использоваться только с массивами значений int. Для работы с другими типами параметров можно было бы либо предоставить соответствующие функции с другими именами, т.е., например, изменить имя на IntArrayMaxValue () и предоставить функции с именами вроде DoubleArrayMaxValue () для обработки других типов, либо добавить в код следующую функцию:
001: 002: 003: 004: 005: 006: 007: 008: 009: 010: 011: 012: 013: |
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. Имя функции — MaxValue () — выглядит точно так же, но вот ее сигнатура (что критически важно) выглядит по-другому. Объясняется это тем, что в сигнатуру функции, как уже рассказывалось ранее, входит как имя функции, так и ее параметры.
Определение двух функций с одинаковыми сигнатурами было бы ошибкой, но благодаря тому, что эти две функции имеют разные сигнатуры, никакой ошибки здесь нет.
Возвращаемый тип функции не является частью ее сигнатуры, поэтому определять две функции, отличающиеся только типом возвращаемого значения, нельзя; их сигнатуры считаются идентичными.
После добавления приведенного выше кода у функции MaxValue () появятся две версии, одна из которых будет принимать в качестве входных данных массив значений типа int и возвращать максимальное значение в нем как число типа int, а вторая— принимать в качестве входных данных массив значений типа double и возвращать максимальное значения в нем в виде числа типа double. Прелесть такого кода состоит в том, что он не требует указывать явным образом, какая именно из этих двух версий должна использоваться.
Достаточно просто предоставить параметр массива и подходящая версия этой функции будет выбрана автоматически в зависимости от того, к какому типу относится параметр.
При перегрузке функций учитываются все аспекты их сигнатур. Например, может существовать две разных версии функции, принимающие параметры, соответственно, по значению и по ссылке:
static void ShowDouble (ref int val)
{
}
static void ShowDouble (int val)
{
}
Решение по поводу того, какая версия должна использоваться, будет приниматься на основании того, содержится в вызове функции ключевое слово ref или нет. Например, следующая строка кода приведет к вызову той версии, которая принимает параметры по ссылке:
ShowDouble(ref val);
Показанная ниже строка кода обеспечит вызов версии, которая принимает параметры по значению:
ShowDouble(val);
В качестве альтернативы можно сделать так, чтобы версии функции отличались друг от друга количеством параметров и т.д.