Теория
Методът е именуван блок от код, който можем да извикваме многократно. Вместо да копираме един и същ код на пет места, го пишем веднъж в метод и го извикваме по име — това е принципът DRY (Don't Repeat Yourself).
Всеки метод има сигнатура: модификатор (засега static), тип на връщане (void, int, string…), име (PascalCase) и параметри в скобите. Параметрите са "входните данни" на метода — локални променливи, които получават стойност при извикването.
Ако методът само върши действие (печата, записва), типът на връщане е void. Ако методът изчислява резултат, указваме типа му и го връщаме с return. След return изпълнението на метода спира незабавно.
Разликата параметри/аргументи: параметрите са имената в декларацията (int a, int b), а аргументите са конкретните стойности при извикване (AddNumbers(10, 15)). Аргументите се копират в параметрите по ред.
Едно име може да носи няколко метода — това е предефиниране (overloading): Sum(int, int) и Sum(double, double) съжителстват спокойно, а компилаторът избира правилния по типовете и броя на аргументите. Така Console.WriteLine работи и с текст, и с числа — то всъщност е предефинирано десетки пъти.
Методите, връщащи bool, са злато за четимостта: if (IsEven(n)) се чете като изречение. Условието често може да се върне директно — return n % 2 == 0; е по-кратко и по-ясно от if-else с return true/return false.
Златни правила
DRY (Don't Repeat Yourself)
Ако пишете един и същ код повече от два пъти — изнесете го в метод. Промените после се правят на едно място вместо на пет.
Една цел
Един метод трябва да прави само едно специфично нещо и да го прави добре. Метод, който "смята, печата и записва във файл", трябва да стане три метода.
void срещу връщан тип
Ако методът само изпълнява действие — void. Ако трябва да върне резултат — указваме типа (напр. int, string) и използваме return.
Името казва какво прави
Методите се именуват с глагол в PascalCase: CalculateArea, PrintGreeting, GetMax. Ако не можете да измислите кратко име — методът вероятно прави твърде много неща.
Бърз справочник
Структура на метод
| Част | Какво представлява? | В примера `static int AddNumbers(int a, int b)` |
|---|---|---|
| Модификатор | Кой има достъп и как се извиква | static (извиква се без обект) |
| Тип на връщане | Какъв резултат връща методът | int (цяло число) |
| Име | Глагол в PascalCase | AddNumbers |
| Параметри | Входните данни на метода | (int a, int b) |
| Тяло | Кодът, който се изпълнява | { return a + b; } |
void срещу връщащ метод
| void метод | Връщащ метод | |
|---|---|---|
| Декларация | static void PrintGreeting(string name) | static int AddNumbers(int a, int b) |
| Има ли return? | Не е задължителен (return; само за ранен изход) | Задължителен — return израз; по всеки път на изпълнение |
| Извикване | PrintGreeting("Иван"); | int sum = AddNumbers(10, 15); |
| Резултат | Само странични действия (печат и др.) | Стойност, която можем да запазим и използваме |
Код за анализ и пренаписване
void метод и метод, връщащ стойност
using System;
namespace ModuleFive
{
class Program
{
static void Main(string[] args)
{
PrintGreeting("Александър"); // Извикване на метод void
int sum = AddNumbers(10, 15); // Извикване на метод връщащ стойност
Console.WriteLine($"Сумата е: {sum}");
}
// Метод, който не връща резултат (void)
static void PrintGreeting(string name)
{
Console.WriteLine($"Здравей, {name}! Добре дошъл в курса по C#.");
}
// Метод, който връща цяло число (int)
static int AddNumbers(int a, int b)
{
return a + b;
}
}
}Какво се случва тук?
-
PrintGreeting("Александър")— аргументът "Александър" се копира в параметъраname. Методът еvoid: върши действие (печата) и не връща нищо. -
AddNumbers(10, 15)връщаint, затова резултатът може да се запази в променлива:int sum = .... Извикване на връщащ метод е израз със стойност. -
return a + b;изчислява сумата и я "предава" обратно на мястото на извикването. Следreturnметодът приключва. - Методите са дефинирани извън
Main, но вътре в класаProgram— редът им няма значение,Mainможе да ги вика независимо дали са написани преди или след него. - И двата метода са
static, защото се извикват директно от статичнияMain, без създаване на обект (повече за това — в Модул 6).
Предефиниране (overloading) и bool методи
using System;
namespace ModuleFiveExtra
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Sum(3, 4)); // вика int версията -> 7
Console.WriteLine(Sum(2.5, 1.5)); // вика double версията -> 4
int number = 7;
if (IsEven(number))
{
Console.WriteLine($"{number} е четно.");
}
else
{
Console.WriteLine($"{number} е нечетно.");
}
}
// Предефиниране: едно име, различни параметри
static int Sum(int a, int b)
{
return a + b;
}
static double Sum(double a, double b)
{
return a + b;
}
// bool метод - именувана проверка
static bool IsEven(int n)
{
return n % 2 == 0; // връщаме директно резултата от сравнението
}
}
}Какво се случва тук?
- Двата метода
Sumимат еднакво име, но различни параметри — това е предефиниране.Sum(3, 4)съвпада с int версията,Sum(2.5, 1.5)— с double. Изборът става още при компилация. - Предефинираните методи трябва да се различават по параметрите (тип, брой или ред) — разлика само във връщания тип не е достатъчна.
-
IsEvenпоказва силата на bool методите:n % 2 == 0вече Еbool, затова го връщаме директно. Без if-else, без излишни редове. - Конвенция: bool методите се именуват като въпрос —
IsEven,IsValid,HasPassed,CanWithdraw. Кодът, който ги ползва, се чете като изречение. - Забележете как
Mainстана по-четим: логиката "какво е четно" е скрита в метода, а вMainостава само намерението.
Внимавай! Чести грешки
Грешките, които почти всеки прави в тази тема — виж разликата между грешния и правилния код.
Методът печата, вместо да връща
Грешно
static void GetMax(int a, int b)
{
Console.WriteLine(a > b ? a : b);
}
// резултатът не може да се ползва по-нататъкПравилно
static int GetMax(int a, int b)
{
return a > b ? a : b;
}
// int max = GetMax(3, 7);Метод, който само печата, е "задънена улица" — резултатът не може да се запази, сравни или преизползва. Правилото: изчисляващите методи връщат, а печата този, който ги вика.
Липсващ return по някой от пътищата
Грешно
static int Sign(int n)
{
if (n > 0)
{
return 1;
}
} // CS0161: not all code paths return a valueПравилно
static int Sign(int n)
{
if (n > 0)
{
return 1;
}
return -1;
}Компилаторът изисква метод с връщан тип да връща стойност по всеки възможен път. Ако n <= 0, лошата версия няма какво да върне → грешка CS0161.
Объркан ред на аргументите
Грешно
static void PrintStudent(string name, int age) { ... }
PrintStudent(20, "Иван"); // CS1503: грешен типПравилно
PrintStudent("Иван", 20);Аргументите се съпоставят с параметрите по ред. При различни типове компилаторът ви спасява; при еднакви (две числа, два низа) — грешката минава тихо и програмата просто работи грешно. Проверявайте реда!
Игнориран резултат
Грешно
AddNumbers(10, 15);
// сумата се изчисли... и изчезнаПравилно
int sum = AddNumbers(10, 15);
Console.WriteLine(sum);Извикването на връщащ метод е израз със стойност — ако не я запазите в променлива (или не я подадете нанякъде), тя се губи. Компилаторът не се оплаква, но програмата "нищо не прави".
Задачи за самостоятелна работа
Опитай първо сам — подсказката е там само ако наистина закъсаш.
Задача 1: GetMax
Напишете метод GetMax(int a, int b), който връща по-голямото от две числа.
Задача 2: Обърнат низ
Напишете метод, който приема низ (string) и го отпечатва наобратно.
Задача 3: Прости числа
Напишете метод IsPrime(int n), който връща дали числото е просто (дели се само на 1 и на себе си). Използвайте го, за да отпечатате всички прости числа от 2 до 50.
Мини-тест за проверка
Отговори си наум (или на глас!) и чак тогава разкрий отговора.
1. Може ли метод от тип void да съдържа ключовата дума return; (без стойност)?
2. Каква е разликата между параметри (parameters) и аргументи (arguments)?
3. Какво е предефиниране (overloading) на методи?
Речник на термините
Виж пълния речник на курса(int a, int b). Получава стойност при извикване.AddNumbers(10, 15) → 10 и 15.int, string, bool…) или void, ако методът само върши действие.Провери знанията
Бърз тест с избор от отговори върху термините на модула — с точки и моментална обратна връзка.
Провери знанията си
8 въпроса върху термините от модула. Показваме определение — ти избираш правилния термин.
Препоръки за този модул
- Тествайте метода самостоятелно: извикайте го с различни аргументи от
Mainи проверете резултатите. - Връщайте резултата, не го печатайте вътре в метода — така методът може да се ползва навсякъде (правилото: изчисляващите методи връщат,
Mainпечата). - Започнете да разпознавате повторения в старите си решения и ги превърнете в методи — отлично упражнение.
- Помнете: променлива, декларирана в метод, съществува само вътре в него (локален обхват / scope).