Przejdź do treści
School IT / Przestrzeń do nauki
← C# od podstawLekcja 19 z 58

Własne metody — nazwij czynność i używaj jej wiele razy

Program kilka razy liczy koszt biletów tym samym wzorem. Zamiast kopiować rachunek, zapiszesz go raz pod własną nazwą — i przy zmianie ceny poprawisz jedno miejsce zamiast dziesięciu.

C# metody return parametry 45–90 min
CEL LEKCJI

Czego się dziś nauczysz

  • Zadeklarujesz metodę z parametrami i typem wyniku.
  • Wywołasz ją i wykorzystasz zwróconą wartość.
  • Odróżnisz parametr od argumentu.
  • Dobierzesz metodę zwracającą wartość albo void.
  • Rozpoznasz komunikat CS0161 i będziesz wiedział, co go powoduje.

Przygotowanie: lekcje 01–18. Przewidywany czas: 45–90 minut z zadaniami. Przykłady wymagają .NET 8 lub nowszego, z włączonymi ImplicitUsings i Nullable.

TEORIA

Trzy razy ten sam rachunek

Program sprzedaje bilety na trzy wydarzenia. Za każdym razem liczy to samo: liczba sztuk razy cena, plus opłata za rezerwację, zaokrąglona do dwóch miejsc.

tak da się, ale nie warto
int sztukiA = 3;
decimal cenaA = 18.50m;
decimal kosztA = sztukiA * cenaA + 2.00m;
Console.WriteLine($"Turniej retro: {kosztA:C}");

int sztukiB = 5;
decimal cenaB = 12.00m;
decimal kosztB = sztukiB * cenaB + 2.00m;
Console.WriteLine($"Noc robotow: {kosztB:C}");

int sztukiC = 2;
decimal cenaC = 24.00m;
decimal kosztC = sztukiC * cenaC + 2.00m;
Console.WriteLine($"Druk 3D: {kosztC:C}");

Kod działa. Problem pojawia się w dniu, w którym opłata za rezerwację rośnie do 2,50 zł — trzeba ją poprawić w trzech miejscach. Przy dziesięciu wydarzeniach w dziesięciu, a jedno na pewno zostanie pominięte.

Metoda to ten rachunek zapisany raz, pod własną nazwą. Reszta programu tylko z niej korzysta:

definicja metody
static decimal Koszt(int sztuki, decimal cena)
{
    return sztuki * cena + 2.00m;
}
użycie
Console.WriteLine($"Turniej retro: {Koszt(3, 18.50m):C}");
Console.WriteLine($"Noc robotow: {Koszt(5, 12.00m):C}");
Console.WriteLine($"Druk 3D: {Koszt(2, 24.00m):C}");

Trzy powody, dla których warto

Po pierwsze: poprawka w jednym miejscu. Po drugie: nazwa Koszt mówi, co się dzieje — czytelnik nie musi rozszyfrowywać wzoru. Po trzecie: metodę da się sprawdzić osobno, bez uruchamiania całego programu. Do tego wrócimy w lekcji 56 przy testach.

TEORIA

Z czego składa się metoda

nagłówek pod lupą
static decimal Koszt(int sztuki, decimal cena)
//  ^^^^^^^ ^^^^^  ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
//     |      |      |            |
//     |      |      |            +-- lista parametrow
//     |      |      +--------------- nazwa metody
//     |      +---------------------- typ zwracanej wartosci
//     +----------------------------- modyfikator
ElementCo oznacza
staticmetodę wywołujemy bez tworzenia obiektu. W programach z tej części kursu zawsze piszemy static; dlaczego — wyjaśni lekcja 44.
decimaltyp wartości, którą metoda oddaje. Może to być każdy typ; void oznacza „nic nie oddaje”.
Kosztnazwa. Piszemy ją PascalCase i tak, żeby mówiła o czynności albo o wyniku (lekcja 05).
(int sztuki, decimal cena)parametry — dane, które metoda dostaje przy każdym wywołaniu. Lista może być pusta: ().

Parametr a argument

To dwa różne słowa na dwie różne rzeczy i warto je rozróżniać, bo komunikaty kompilatora ich używają.

PojęcieGdzie występujePrzykład
parametrw deklaracji metodyint sztuki — nazwa i typ, bez wartości
argumentw miejscu wywołaniaKoszt(3, 18.50m) — konkretna wartość, tu 3

Kolejność argumentów ma znaczenie

Wywołanie Koszt(18.50m, 3) nie skompiluje się, bo typy nie pasują — i całe szczęście. Gdyby oba parametry były typu int, kompilator przyjąłby zamianę bez słowa, a program liczyłby bzdury. Argumenty trafiają do parametrów po kolei, a nie po nazwie.

TEORIA

Oddawanie wyniku

return robi dwie rzeczy naraz: kończy wykonanie metody i oddaje wartość do miejsca wywołania.

definicja metody
static int Wieksza(int a, int b)
{
    if (a > b)
    {
        return a;       // tutaj metoda sie konczy
    }

    return b;           // ta linia wykona sie tylko wtedy, gdy a <= b
}

Instrukcje zapisane po wykonanym return nigdy się nie wykonają — kompilator zgłosi je jako kod nieosiągalny (ostrzeżenie CS0162).

Metoda void

Gdy metoda ma coś zrobić, a nie coś policzyć, jej typem wyniku jest void.

definicja metody
static void Naglowek(string tytul)
{
    Console.WriteLine();
    Console.WriteLine(tytul.ToUpper());
    Console.WriteLine(new string('-', tytul.Length));
}

Taką metodę wywołujemy jako osobną instrukcję: Naglowek("Sprzedaż");. Nie da się jej użyć w wyrażeniu, bo nie ma czego wstawić.

Najczęstsze pytanie tej lekcji

„Dlaczego metoda nic nie wypisuje?” — bo return nie wypisuje. Oddaje wartość temu, kto metodę wywołał, a ten musi z nią coś zrobić: przypisać do zmiennej albo wstawić do Console.WriteLine. Samo Koszt(3, 18.50m); jako instrukcja policzy wynik i natychmiast go wyrzuci.

Zadanie metodyTyp wynikuJak wywołać
policzyć i oddać liczbęint, decimal, doubledecimal x = Koszt(3, 18.50m);
odpowiedzieć tak albo nieboolif (CzyPelnoletni(wiek)) …
zbudować tekststringConsole.WriteLine(Opis(3));
wypisać, narysować, zapisaćvoidNaglowek("Sprzedaż");
TEORIA

Gdzie w pliku umieścić metodę

Od lekcji 03 znasz dwa sposoby zapisania programu. Metody można pisać w obu, ale wyglądają trochę inaczej.

W klasie Program — zapis klasyczny

Program.cs
class Program
{
    static decimal Koszt(int sztuki, decimal cena)
    {
        return sztuki * cena + 2.00m;
    }

    static void Main()
    {
        Console.WriteLine(Koszt(3, 18.50m));
    }
}

Koszt i Main są na tym samym poziomie — obie wewnątrz klasy, żadna wewnątrz drugiej. Kolejność nie ma znaczenia: metoda może być zapisana pod Main i i tak zostanie znaleziona.

W instrukcjach najwyższego poziomu

Program.cs
Console.WriteLine(Koszt(3, 18.50m));

static decimal Koszt(int sztuki, decimal cena)
{
    return sztuki * cena + 2.00m;
}

Tutaj metody zapisujemy pod instrukcjami wykonywalnymi. To ta sama metoda, tylko krócej zapisana.

Metoda w metodzie

Wklejenie definicji Koszt wewnątrz klamer Main też się skompiluje — powstanie wtedy funkcja lokalna, widoczna tylko w Main. W tym kursie tak nie robimy: metody mają być dostępne dla całego programu. Sprawdź wcięcia — klamra zamykająca Main musi stać przed nagłówkiem kolejnej metody.

PRZYKŁAD

Przykład: kasa biletowa

Wklej cały przykład do nowego projektu konsolowego jako Program.cs. Zanim uruchomisz — przewidź wynik.

Program.cs
class Program
{
    static decimal Koszt(int sztuki, decimal cena)
    {
        return sztuki * cena + 2.00m;      // 2 zl oplaty za rezerwacje
    }

    static bool CzyZnizka(int wiek)
    {
        return wiek < 18 || wiek >= 65;
    }

    static string Opis(string wydarzenie, int sztuki)
    {
        if (sztuki == 1)
        {
            return $"{wydarzenie}: jeden bilet";
        }

        return $"{wydarzenie}: {sztuki} biletow";
    }

    static void Naglowek(string tytul)
    {
        Console.WriteLine();
        Console.WriteLine(tytul.ToUpper());
        Console.WriteLine(new string('-', tytul.Length));
    }

    static void Main()
    {
        Naglowek("Kasa biletowa");

        Console.WriteLine(Opis("Turniej retro", 3));
        Console.WriteLine($"Do zaplaty: {Koszt(3, 18.50m):F2} zl");

        Console.WriteLine(Opis("Noc robotow", 1));
        Console.WriteLine($"Do zaplaty: {Koszt(1, 12.00m):F2} zl");

        Naglowek("Znizki");

        int[] wieki = { 15, 30, 70 };          // tablice poznasz w lekcji 23
        foreach (int wiek in wieki)
        {
            Console.WriteLine($"wiek {wiek,2}: znizka {CzyZnizka(wiek)}");
        }
    }
}
wynik w konsoli
KASA BILETOWA
-------------
Turniej retro: 3 biletow
Do zaplaty: 57,50 zl
Noc robotow: jeden bilet
Do zaplaty: 14,00 zl

ZNIZKI
------
wiek 15: znizka True
wiek 30: znizka False
wiek 70: znizka True

Co dzieje się po kolei

  • Cztery metody, cztery różne typy wyniku: decimal, bool, string i void. Każda robi jedną rzecz i tyle.
  • Naglowek wywołujemy dwa razy z różnym argumentem — linia pod tytułem sama dopasowuje długość, bo powstaje z tytul.Length.
  • CzyZnizka zwraca bool, więc wynik wyrażenia logicznego wystarczy oddać przez return — nie trzeba pisać if … return true; else return false;.
  • Opis ma dwa return. Pierwszy kończy metodę dla jednego biletu; drugi wykona się tylko w pozostałych przypadkach.
  • Metody stoją nad Main, ale wykonują się dopiero wtedy, gdy Main je wywoła. Sama definicja niczego nie uruchamia.
ELEMENTY WBUDOWANE

Co robi każdy użyty element

ElementZwracaDziałanie i ograniczenia
static typ Nazwa(parametry)—Deklaracja metody. Bez static w tej części kursu metoda nie zostanie znaleziona z Main.
return wartosc;—Kończy metodę i oddaje wartość. Typ musi zgadzać się z nagłówkiem, inaczej błąd CS0029.
return;—W metodzie void: wcześniejsze zakończenie. Przydatne do odrzucenia błędnych danych na początku.
voidtypMetoda nic nie oddaje. Nie wolno jej użyć w wyrażeniu ani przypisać do zmiennej.
Nazwa(argumenty)zależnie od metodyWywołanie. Argumenty trafiają do parametrów po kolei, nie po nazwie.
new string(znak, n)stringNapis z n powtórzeń znaku — wygodna linia oddzielająca.
tekst.ToUpper()stringWersja wielkimi literami; oryginału nie zmienia (lekcja 08).
{liczba:F2}tekstFormatowanie do dwóch miejsc po przecinku (lekcja 13).
CZĘSTE BŁĘDY

Zanim utkniesz

ZapisProblem
Koszt(3, 18.50m); jako osobna instrukcjaWynik zostaje policzony i wyrzucony. Przypisz go albo wstaw do Console.WriteLine.
Brak return na którejś ścieżceCS0161: „nie wszystkie ścieżki kodu zwracają wartość”. Każde rozgałęzienie if musi kończyć się return albo trzeba dopisać jeden na końcu metody.
Console.WriteLine zamiast returnMetoda wypisze wynik, ale odda void — nie da się go użyć w dalszych obliczeniach. Licz w metodzie, wypisuj w Main.
Definicja metody wewnątrz MainPowstaje funkcja lokalna widoczna tylko tam. Sprawdź, gdzie stoi klamra zamykająca Main.
Brak staticCS0120: „wymagane jest odwołanie do obiektu”. W tej części kursu wszystkie metody są static.
Zamienione argumenty tego samego typuKompilator nie ma jak tego wykryć. Program policzy coś innego niż zamierzałeś — sprawdź kolejność w nagłówku.
Metoda robiąca trzy rzeczy narazKompiluje się, ale nazwać ją sensownie już się nie da. Jeśli w nazwie musi być „i”, to są dwie metody.
ZADANIA

Zadania

ZAD 1Pole prostokąta★☆☆

Napisz metodę static int Pole(int a, int b) zwracającą pole prostokąta i wywołaj ją trzy razy z różnymi wymiarami. Wypisz wyniki w Main, nie w metodzie.

ZAD 2Powitanie★☆☆

Napisz metodę static void Powitaj(string imie), która wypisuje Czesc, Ala!. Wywołaj ją dla trzech imion. Wyjaśnij w komentarzu, dlaczego ta metoda ma typ void, a poprzednia int.

ZAD 3Większa z dwóch★☆☆

Napisz metodę static int Wieksza(int a, int b). Sprawdź ją dla par (3, 8), (8, 3) i (5, 5). Zapisz, co metoda zwraca dla liczb równych i czy to poprawne.

ZAD 4Ocena słownie★★☆

Napisz metodę static string Slownie(int ocena), która dla liczb od 1 do 6 zwraca nazwę oceny, a dla pozostałych napis brak oceny. Wypisz wyniki dla 0, 1, 4, 6 i 7. Metoda nie może niczego wypisywać samodzielnie.

ZAD 5Trzy metody, jeden rachunek★★☆

Napisz program kasy biletowej z trzema metodami: Netto(int sztuki, decimal cena), Vat(decimal netto) licząca 23 procent i Brutto(decimal netto) korzystająca z Vat. Wypisz wszystkie trzy kwoty dla 4 biletów po 15 zł. Żadna z metod nie wypisuje wyniku.

ZAD 6Kalkulator z menu★★★

Napisz program z menu: dodawanie, odejmowanie, mnożenie i dzielenie. Każde działanie ma być osobną metodą zwracającą wynik, a pętla z menu ma tylko wczytywać dane, wywoływać właściwą metodę i wypisywać wynik. Dzielenie przez zero obsłuż tak, żeby program się nie przerwał, i zapisz w komentarzu, którą drogę wybrałeś oraz dlaczego.

PODSUMOWANIE

Co trzeba zapamiętać

  • Metoda to nazwany fragment programu, który można wywołać wiele razy z różnymi danymi.
  • Nagłówek metody to modyfikator, typ wyniku, nazwa i lista parametrów.
  • Parametr stoi w deklaracji, argument w wywołaniu; trafiają do siebie po kolei.
  • return kończy metodę i oddaje wartość — nie wypisuje jej.
  • Metoda void coś robi, zamiast coś oddawać, i nie da się jej użyć w wyrażeniu.
  • Jedna metoda ma robić jedną rzecz; obliczenia trzymaj w metodach, a wypisywanie w Main.

Dokumentacja: Microsoft Learn — temat tej lekcji.

Postęp zapisuje się w tej przeglądarce.