4_Методы
Урок 4 : Методы
Методы - именованные блоки кода, которые можно вызывать многократно. Они делают программу структурированной и избавляют от повторений.
1. Что такое метод
Метод - это как рецепт блюда: написан один раз, а приготовить по нему (вызвать) можно сколько угодно раз, передавая разные ингредиенты (аргументы).
Именованный блок кода, выполняющий определённую задачу. Объявляется один раз, вызывается сколько угодно раз.
// Без методов - дублирование кода:
Console.WriteLine("Добро пожаловать!");
Console.WriteLine("Игра началась.");
Console.WriteLine("Добро пожаловать!"); // снова то же самое
Console.WriteLine("Игра началась.");
// С методом - один раз объявили, вызываем сколько нужно:
void ShowWelcome()
{
Console.WriteLine("Добро пожаловать!");
Console.WriteLine("Игра началась.");
}
ShowWelcome(); // первый вызов
ShowWelcome(); // второй вызов
2. Сигнатура метода
Сигнатура - это «паспорт» метода, по которому компилятор его идентифицирует.
[модификаторы] возвращаемый_тип ИмяМетода(тип параметр1, тип параметр2, ...)
↓ ↓ ↓ ↓
static int Add (int a, int b)
| Часть | Описание | Пример |
|---|---|---|
| Модификаторы | Область доступа и поведение | public, static, private |
| Возвращаемый тип | Тип значения, которое метод возвращает | int, string, void |
| Имя метода | Идентификатор | Add, GetName, PrintInfo |
| Параметры | Входные данные (может быть пустым) | (int a, int b), () |
// Полный пример сигнатуры
public static int Add(int a, int b)
{
return a + b;
}
3. Метод Main - точка входа
Main - специальный метод, с которого начинается выполнение программы. Вызывается автоматически операционной системой.
// Стандартная точка входа
static void Main(string[] args)
{
// всё начинается здесь
}
// Современный вариант (без явного класса и Main)
// - работает в C# 9+, но в Unity не используется
В Unity точкой входа служат методы жизненного цикла MonoBehaviour: Awake(), Start(), Update(). Но принцип тот же - определённые методы вызываются автоматически.
4. Возвращаемый тип
Метод может возвращать значение с помощью оператора return.
// void - ничего не возвращает
void PrintGreeting(string name)
{
Console.WriteLine($"Привет, {name}!");
// return; // можно написать явно, но необязательно
}
// int - возвращает целое число
int Multiply(int a, int b)
{
return a * b; // return обязателен
}
// bool - возвращает логическое значение
bool IsEven(int number)
{
return number % 2 == 0;
}
// string - возвращает строку
string GetStatus(int health)
{
if (health > 50) return "Хорошо";
if (health > 0) return "Плохо";
return "Мёртв";
}
Код после return не выполнится. Это можно использовать для ранних выходов из метода.
void ProcessOrder(int quantity)
{
if (quantity <= 0)
{
Console.WriteLine("Некорректное количество");
return; // выходим из метода, код ниже не выполнится
}
// обрабатываем заказ...
Console.WriteLine($"Обработка {quantity} единиц");
}
5. Параметры и аргументы
Параметр - переменная в объявлении метода (шаблон).
Аргумент - конкретное значение при вызове.
// Параметры: name и age - это параметры
void Greet(string name, int age)
{
Console.WriteLine($"{name}, вам {age} лет");
}
// Аргументы: "Алексей" и 25 - это аргументы
Greet("Алексей", 25);
Greet("Мария", 30);
// Именованные аргументы (порядок не важен)
Greet(age: 25, name: "Алексей");
6. Перегрузка методов (Overloading)
Несколько методов с одинаковым именем, но разными параметрами. Компилятор выбирает нужный вариант по типу и количеству аргументов.
// Перегруженные методы Print
void Print(int value)
{
Console.WriteLine($"int: {value}");
}
void Print(string value)
{
Console.WriteLine($"string: {value}");
}
void Print(int a, int b)
{
Console.WriteLine($"sum: {a + b}");
}
// Компилятор выбирает нужный вариант автоматически
Print(42); // вызовет Print(int)
Print("Hello"); // вызовет Print(string)
Print(3, 4); // вызовет Print(int, int)
В Unity часто встречается перегрузка: Instantiate(prefab) и Instantiate(prefab, position, rotation) - это разные перегрузки одного метода.
7. Параметры по умолчанию
Параметр с дефолтным значением необязателен при вызове.
void ShowMessage(string text, bool showBorder = false, int repeat = 1)
{
for (int i = 0; i < repeat; i++)
{
if (showBorder) Console.WriteLine("---");
Console.WriteLine(text);
}
}
// Все три варианта корректны:
ShowMessage("Привет"); // showBorder=false, repeat=1
ShowMessage("Привет", true); // repeat=1
ShowMessage("Привет", true, 3); // все явно
// Именованные параметры позволяют пропускать
ShowMessage("Привет", repeat: 3); // showBorder остаётся false
Параметры со значением по умолчанию должны стоять после обязательных параметров.
void Bad(int a = 0, int b) {} // ОШИБКА
void Good(int b, int a = 0) {} // Норма
Для углублённого изучения
Модификаторы параметров: ref, out, params
По умолчанию значимые типы передаются по значению (копия). Модификаторы меняют это поведение.
ref - передача по ссылке (чтение и запись)
void Double(ref int value)
{
value *= 2; // изменяем оригинал
}
int x = 5;
Double(ref x);
Console.WriteLine(x); // 10 - оригинал изменился!
out - параметр только для вывода
// out: метод обязан присвоить значение параметру
bool TryParse(string input, out int result)
{
if (int.TryParse(input, out result))
return true;
result = 0; // обязательно присвоить
return false;
}
if (TryParse("42", out int number))
Console.WriteLine(number); // 42
int.TryParse(), double.TryParse() - стандартные методы с out. Это безопасный способ конвертировать строку в число без исключения.
params - переменное число аргументов
int Sum(params int[] numbers)
{
int total = 0;
foreach (int n in numbers)
total += n;
return total;
}
Console.WriteLine(Sum(1, 2, 3)); // 6
Console.WriteLine(Sum(10, 20)); // 30
Console.WriteLine(Sum(1, 2, 3, 4, 5)); // 15
Стек вызовов и рекурсия
Стек вызовов (Call Stack)
При каждом вызове метода в памяти создаётся стековый фрейм - блок с локальными переменными и адресом возврата. Методы выполняются по принципу стека (LIFO).
Main() вызывает A()
A() вызывает B()
B() вызывает C()
C() завершается → фрейм C удаляется
B() завершается → фрейм B удаляется
A() завершается → фрейм A удаляется
Main() продолжает работу
Рекурсия
Метод вызывает сам себя. Обязательно должно быть базовое условие (выход из рекурсии).
// Рекурсивное вычисление факториала
int Factorial(int n)
{
if (n <= 1) return 1; // базовый случай - выход из рекурсии
return n * Factorial(n - 1); // рекурсивный вызов
}
Console.WriteLine(Factorial(5)); // 5 * 4 * 3 * 2 * 1 = 120
StackOverflowException
Если рекурсия не завершается (нет базового условия или оно никогда не выполнится) - стек переполняется и программа аварийно завершается.
// ОПАСНО: бесконечная рекурсия
int Infinite(int n)
{
return Infinite(n + 1); // нет условия выхода → StackOverflowException
}
Итог урока
- Метод = имя + возвращаемый тип + параметры + тело
Main- точка входа программы, вызывается автоматическиvoid- метод ничего не возвращает;return T- возвращает значение типаT- Параметр - в объявлении; аргумент - при вызове
- Перегрузка - несколько методов с одним именем, но разными параметрами
- Дефолтные значения - делают параметры необязательными
ref- по ссылке;out- только на вывод;params- произвольное число аргументов- Стек вызовов - LIFO; рекурсия без базового условия →
StackOverflowException
📋 Перейти к практическим заданиям урока 4
Материалы для дополнительного ознакомления :
Методы
Параметры методов
Оператор return
Модификаторы параметров out, ref, in
Массив параметров
Рекурсия
Локальные функции
Перегрузка методов