Перейти к содержанию
Educora
Начальный18 мин5 / 16

Методы: параметры, возвращаемые значения, ref и out

Пиши собственные методы: параметры, `return`, краткая запись `=>`, необязательные и именованные аргументы, кортежи, `ref` и `out`.

Проверь себя
В этом уроке ты узнаешь
  • Определять метод с параметрами и вызывать его
  • Возвращать результат через return и объяснять отличие от методов void
  • Использовать необязательные параметры и именованные аргументы
  • Отличать передачу по значению от передачи через ref и out

Ты в пяти местах программы считаешь цену со скидкой и каждый раз копируешь одни и те же три строки. Потом находишь в формуле ошибку — и исправлять её приходится в пяти местах! Методы решают эту проблему: код пишется один раз, получает имя и вызывается сколько угодно раз. Console.WriteLine, int.Parse и string.Join — уже знакомые тебе методы, а теперь ты напишешь свои.

Определение и вызов метода

В заголовке метода сначала пишется тип возвращаемого значения, затем имя, а в скобках — параметры с их типами. void означает, что метод ничего не возвращает. В программе с операторами верхнего уровня методы обычно размещают в конце файла, но вызывать их можно и выше. Имена методов начинаются с заглавной буквы: Greet, CalculateTotal.

C#
Greet("Aysel");
Greet("Murad");

void Greet(string name)
{
    Console.WriteLine($"Salam, {name}!");
}
Ожидаемый результат
Salam, Aysel!
Salam, Murad!
Определение
Параметр и аргумент

Параметр — переменная, объявленная в заголовке метода (string name). Аргумент — конкретное значение, которое передаётся этому параметру при вызове ("Aysel").

return: возврат результата

Если метод возвращает результат, вместо void пишут тип результата, а в теле используют return. return завершает метод и отправляет значение в место вызова. Метод, тело которого состоит из одного выражения, можно кратко записать со стрелкой =>.

C#
double area = RectangleArea(4, 3.5);
Console.WriteLine($"Room area: {area}");
Console.WriteLine(IsEven(10));
Console.WriteLine(CelsiusToFahrenheit(25));

double RectangleArea(double width, double height)
{
    return width * height;
}

bool IsEven(int n) => n % 2 == 0;

double CelsiusToFahrenheit(double c) => c * 9 / 5 + 32;
Ожидаемый результат
Room area: 14
True
77

Необязательные параметры и именованные аргументы

Параметру можно задать значение по умолчанию: если аргумент при вызове опущен, используется оно. Такие параметры пишут в конце списка. Аргументы можно передавать и по имени — discount: 10, тогда их порядок не важен, а смысл вызова сразу понятен.

C#
Console.WriteLine(FinalPrice(80));
Console.WriteLine(FinalPrice(80, 25));
Console.WriteLine(FinalPrice(discount: 10, price: 50));

PrintTicket("Leyla");
PrintTicket("Elvin", seats: 3);

decimal FinalPrice(decimal price, int discount = 0)
{
    return price - price * discount / 100;
}

void PrintTicket(string name, string city = "Baku", int seats = 1)
{
    Console.WriteLine($"{name}: {seats} seat(s) in {city}");
}
Ожидаемый результат
80
60
45
Leyla: 1 seat(s) in Baku
Elvin: 3 seat(s) in Baku
Так как seats: 3 передан по имени, параметр city удалось пропустить.

Несколько результатов: кортежи, ref и out

Метод может вернуть сразу несколько значений в виде кортежа (tuple): тип результата пишется в скобках, например (int Min, int Max). При вызове кортеж можно сразу разложить на отдельные переменные:

C#
int[] temperatures = [12, 5, 27, 9];
var (low, high) = MinMax(temperatures);
Console.WriteLine($"Min: {low}, max: {high}");

(int Min, int Max) MinMax(int[] numbers)
{
    int min = numbers[0];
    int max = numbers[0];
    foreach (int n in numbers)
    {
        if (n < min) min = n;
        if (n > max) max = n;
    }
    return (min, max);
}
Ожидаемый результат
Min: 5, max: 27

По умолчанию аргументы передаются по значению: метод получает копию, и даже если меняет её, переменная у вызывающей стороны не меняется. Ключевое слово ref передаёт саму переменную — метод может её изменить. out служит для выдачи результатов: метод обязан записать значение в параметр out. И ref, и out пишутся и в заголовке метода, и при вызове.

C#
int score = 10;
AddBonusCopy(score);
Console.WriteLine($"After copy: {score}");
AddBonus(ref score);
Console.WriteLine($"After ref: {score}");

Divide(17, 5, out int quotient, out int remainder);
Console.WriteLine($"17 / 5 = {quotient}, remainder {remainder}");

if (int.TryParse("42", out int number))
    Console.WriteLine($"Parsed: {number}");
if (!int.TryParse("forty", out _))
    Console.WriteLine("'forty' is not a number");

void AddBonusCopy(int value) => value += 5;

void AddBonus(ref int value) => value += 5;

void Divide(int x, int y, out int q, out int r)
{
    q = x / y;
    r = x % y;
}
Ожидаемый результат
After copy: 10
After ref: 15
17 / 5 = 3, remainder 2
Parsed: 42
'forty' is not a number
  • AddBonusCopy изменил только копию, поэтому score остался равен 10.
  • С ref метод получил саму переменную и сделал её равной 15.
  • int.TryParse работает через out: если преобразование удалось, возвращает true и записывает число, иначе возвращает false, не выбрасывая ошибку. out _ означает, что результат нам не нужен.

Главное

  • Заголовок метода: тип результата, имя, параметры — double Area(double w, double h).
  • Метод void ничего не возвращает; остальные возвращают значение через return.
  • Метод из одного выражения можно кратко записать через =>.
  • Значения по умолчанию (int discount = 0) делают аргумент необязательным, а именованные аргументы (seats: 3) освобождают от порядка.
  • По умолчанию аргументы передаются копиями; ref передаёт саму переменную, а out выдаёт результат наружу.

Проверь себя

Вопросов: 10. Каждый правильный ответ приносит XP.

1 / 10
Что означает тип результата void?