Модул 5

Методи (Функции)

Как да разделим програмата на малки, преизползваеми парчета — деклариране и извикване на методи, void срещу връщащи методи, параметри, аргументи и return.

Теория

Методът е именуван блок от код, който можем да извикваме многократно. Вместо да копираме един и същ код на пет места, го пишем веднъж в метод и го извикваме по име — това е принципът 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 (цяло число)
ИмеГлагол в PascalCaseAddNumbers
ПараметриВходните данни на метода(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 метод и метод, връщащ стойност

Program.cs
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 методи

Program.cs
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) на методи?

Речник на термините

Виж пълния речник на курса
Метод
Именуван блок код, който може да се извиква многократно — с входни данни (параметри) и евентуален резултат (return).
Параметър
Променлива в декларацията на метода: (int a, int b). Получава стойност при извикване.
Аргумент
Конкретната стойност, подадена при извикването: AddNumbers(10, 15) → 10 и 15.
Връщан тип
Типът на резултата (int, string, bool…) или void, ако методът само върши действие.
Сигнатура
Името на метода + типовете и редът на параметрите — това, по което компилаторът го разпознава.
Предефиниране (overloading)
Няколко метода с едно име, но различни параметри — компилаторът избира по аргументите.
Обхват (scope)
Областта, в която едно име съществува. Променлива, декларирана в метод, живее само в него.
DRY
"Don't Repeat Yourself" — повтарящ се код се изнася в метод, за да се променя на едно място.

Провери знанията

Бърз тест с избор от отговори върху термините на модула — с точки и моментална обратна връзка.

Провери знанията си

8 въпроса върху термините от модула. Показваме определение — ти избираш правилния термин.

Препоръки за този модул

  • Тествайте метода самостоятелно: извикайте го с различни аргументи от Main и проверете резултатите.
  • Връщайте резултата, не го печатайте вътре в метода — така методът може да се ползва навсякъде (правилото: изчисляващите методи връщат, Main печата).
  • Започнете да разпознавате повторения в старите си решения и ги превърнете в методи — отлично упражнение.
  • Помнете: променлива, декларирана в метод, съществува само вътре в него (локален обхват / scope).

Начален курс по C# — учебен наръчник и бърз справочник за студенти.

Натисни Ctrl K или / отвсякъде, за да търсиш.