Свои методы
Чему вы научитесь:
- объявлять методы с параметрами и возвращаемым значением;
- вызывать методы с именованными аргументами и значениями по умолчанию;
- объяснять, почему метод меняет только копию аргумента, и передавать саму переменную через
refиout; - писать рекурсивные методы с базовым случаем.

Представьте необычный копировальный аппарат. Вы кладёте на стекло листы с числами, нажимаете кнопку, и аппарат выдаёт готовый лист: например, копию того листа, где число больше. Как он устроен внутри, думать не нужно: достаточно знать, что положить на стекло и что выйдет из лотка. И пользоваться им можно сколько угодно раз, каждый раз с другими листами.
В программе такой аппарат называется методом. Метод — это кусок кода с именем: ему передают значения, он выполняет с ними свои инструкции и может вернуть результат.
Зачем он нужен? Допустим, программе в трёх местах нужно выбрать большее из двух чисел. Без метода вы трижды напишете один и тот же if, а найдя в нём ошибку, будете исправлять её трижды. С методом вы пишете проверку один раз, а в нужных местах вызываете метод по имени:
Console.WriteLine(Max(3, 8)); // 8
Console.WriteLine(Max(10, -2)); // 10
int Max(int a, int b)
{
if (a > b)
{
return a;
}
return b;
}Давайте разберём, что происходит при первом вызове:
Max(3, 8)вызывает метод: значение3попадает вa, а8— вb.- Тело метода выполняется сверху вниз. Условие
3 > 8ложно, поэтомуreturn a;пропускается. return b;завершает метод и отдаёт8туда, откуда его вызвали.Console.WriteLineпечатает8.
Второй вызов проходит тот же путь с другими числами: 10 > -2 истинно, и метод возвращает 10.
Объявление метода
Первая строка объявления, int Max(int a, int b), состоит из трёх частей:
int— тип результата: значение какого типа метод отдаст обратно;Max— имя метода; в C# методы называют с большой буквы;(int a, int b)— параметры: тип и имя каждого, через запятую.
За первой строкой в фигурных скобках идёт тело — инструкции, которые выполняются при каждом вызове.
Параметры и аргументы
В примере встретились два слова, которые часто путают:
- параметр — переменная из объявления метода:
aиbвint Max(int a, int b); - аргумент — значение, которое передают при вызове:
3и8вMax(3, 8).
Аргументы попадают в параметры по порядку: первый в первый, второй во второй. Число и типы аргументов компилятор сверяет с объявлением. Аргументом может быть любое выражение подходящего типа: вызов Max(x + 1, 5) сначала вычислит x + 1.
О разнице между параметром и аргументом иногда спрашивают на собеседованиях для начинающих.
Инструкция return
return делает две вещи сразу:
- отдаёт значение туда, откуда вызвали метод;
- тут же завершает метод: строки после сработавшего
returnуже не выполняются.
Метод с типом результата обязан дойти до return на любом пути через тело. В Max таких путей два: через return a; и через return b;.
Методы без результата
Здесь аналогия с копировальным аппаратом перестаёт работать. Аппарат всегда выдаёт лист, а метод может ничего не возвращать: например, только выводить текст на экран. Вместо типа результата у такого метода стоит void:
Greet("Anna"); // Hello, Anna!
Greet("Oleg"); // Hello, Oleg!
void Greet(string name)
{
Console.WriteLine("Hello, " + name + "!");
}Greet("Anna") выполняет тело, в котором name равен "Anna", и печатает приветствие. Вызов такого метода — отдельная инструкция: его нельзя передать в Console.WriteLine или записать в переменную. Строка int x = Greet("Anna"); не скомпилируется, ведь void значит «результата нет».
В методе void тоже можно написать return;, без значения: такая инструкция сразу завершает метод.
Короткая форма через =>
Если метод вычисляет одно выражение, фигурные скобки и return можно заменить стрелкой =>:
Console.WriteLine(Square(4)); // 16
int Square(int n) => n * n;int Square(int n) => n * n; значит то же, что тело { return n * n; }. Такую форму используют для коротких методов, в том числе для методов void.
Где объявлять метод
В программе из инструкций верхнего уровня метод объявляют прямо среди инструкций. Обычно методы ставят в конец файла, как в примерах этого урока. Вызвать метод можно и выше его объявления: компилятор видит такой метод во всех инструкциях верхнего уровня, а не только в тех, что ниже.
Формально такой метод называется локальной функцией. Помните метод-точку входа <Main>$, который компилятор строит вокруг инструкций верхнего уровня? Ваш метод попадает внутрь него. Сам <Main>$ объявлен внутри класса Program — это метод класса. Методы класса устроены так же: тип результата, имя, параметры и тело.
Частая ошибка
В методе есть путь, на котором return не встречается:
Console.WriteLine(Max(3, 8));
int Max(int a, int b) // ✗
{
if (a > b)
{
return a;
}
}error CS0161: 'Max(int, int)': not all code paths return a valueПрограмма не компилируется. Компилятор не запускает её и не знает, какие числа придут в Max, поэтому проверяет все пути через тело. Если a > b ложно, метод доходит до закрывающей скобки без return, и вернуть ему нечего. Исправление — последняя строка return b;, как в первом примере.
Главное
- Метод объявляют так: тип результата, имя, параметры в скобках и тело; вызывают по имени, передавая аргументы.
- Параметр — переменная из объявления, аргумент — значение из вызова.
returnотдаёт результат и сразу завершает метод; метод с типом результата должен дойти доreturnна любом пути, а методvoidничего не возвращает.- Метод, объявленный среди инструкций верхнего уровня, формально называется локальной функцией.