Meetodid

C# programmeerimiskeeles on meetod koodiplokk, mis sisaldab rida lauseid. Programm paneb need laused täituma, kutsudes meetodit välja ja täpsustades vajadusel meetodi argumendid. C#-s sooritatakse iga täidetav instruktsioon meetodi kontekstis.

Siin on põhjalik ülevaade meetoditega seotud mõistetest ja reeglitest:

1. Meetodi allkiri (Signature) ja deklaratsioon

Meetodid deklareeritakse klassis, struktuuris või liideses, määrates ära järgmised osad, mis moodustavad meetodi allkirja:

  • Pääsutase (Access level): Näiteks public (avalik) või private (privaatne).
  • Valikulised modifikaatorid: Näiteks abstract (abstraktne) või sealed (suletud).
  • Tagastusväärtus (Return value): Tüüp, mille meetod tagastab, või void, kui meetod väärtust ei tagasta.
  • Nimi: Meetodi identifikaator.
  • Parameetrid: Sulgudes olevad tüübid ja nimed, mis eraldatakse komadega.

2. Parameetrid vs argumendid

Allikad teevad selget vahet kahel mõistel:

  • Parameetrid: Määratletakse meetodi definitsioonis (nimed ja tüübid).
  • Argumendid: Konkreetsed väärtused, mida kutsuv kood meetodile edastab. Need peavad ühilduma parameetri tüübiga, kuid argumendi nimi koodis ei pea kattuma parameetri nimega definitsioonis.

3. Väärtuse ja viitega edastamine

  • Väärtustüübid: Vaikimisi edastatakse väärtustüübi (nt int, struct) puhul meetodile selle koopia. Muudatused argumendis ei mõjuta algset väärtust.
  • Viitetüübid: Viitetüübi (nt class) puhul edastatakse viide objektile. Kui muudate objekti liiget meetodi sees, kajastub see ka kutsuvas koodis, isegi kui objekt edastati väärtusena.
  • ref ja out märksõnad: Kasutades ref märksõna, saab väärtustüüpe edastada viitega. out parameeter sarnaneb ref-ile, kuid see peab saama meetodi sees väärtuse enne meetodi lõppemist.

4. Eritüüpi meetodid

  • Asünkroonid meetodid (async ja await): Võimaldavad kutsuda asünkroonseid toiminguid ilma keeruliste tagasikutseteta (callbacks). Need meetodid tagastavad tavaliselt Task, Task<T> või void (viimast peamiselt sündmuste käsitlejate puhul). Asünkroonsetes meetodites ei saa kasutada ref ega out parameetreid.
  • Lühivormid (Expression body definitions): Kui meetod sisaldab ainult ühte lauset või tagastab kohe avaldise tulemuse, saab kasutada lühendatud süntaksit =>.
  • Laiendusmeetodid (Extension methods): Võimaldavad lisada uusi meetodeid olemasolevatele tüüpidele ilma neid muutmata või neist pärimata. C# 14 tõi sisse ka laiendusliikmed (extension members), mis võimaldavad laiendusi loogiliselt grupeerida.
  • Lokaalsed funktsioonid: Meetodi sees defineeritud funktsioonid, millel on juurdepääs ümbritseva meetodi muutujatele. Need on kasulikud koodi korrastamiseks ja neid saab kasutada ainult selles meetodis, kus nad on loodud.

5. Sisenemispunkt: Main meetod

Iga C# rakenduse sisenemispunkt on Main meetod, mille CLR kutsub välja programmi käivitamisel. See on staatiline meetod ja asub tavaliselt klassi sees. Uuemates versioonides (C# 9.0+) saab kasutada ka top-level statements lähenemist, kus kompilaator genereerib Main meetodi automaatselt.

6. Tagastusväärtused ja väljumine

Meetod lõpetab töö, kui jõuab koodiploki lõppu või kohtab return lauset. Kui meetodi tagastustüüp ei ole void, peab see alati kasutama return märksõna vastavat tüüpi väärtuse tagastamiseks. Väärtusi saab tagastada ka viitega, kasutades ref return süntaksit

Minu näided :

public class StartPage
    {
        static void Main(string[] args)
        {
            Console.WriteLine("vali funktisoon");
            Console.WriteLine("1 - retsepti sisestamine");
            Console.WriteLine("2 - retsepti lugemine");
            Console.WriteLine("3 - koostis osade faili tekkimine");
            Console.WriteLine("4 - koostis osade lugemine");
            Console.WriteLine("5 - koostis osade muutmine ");
            Console.WriteLine("6 - Koostisosa otsing");
            int[] arvud = new int[5];
            string valik = Console.ReadLine();
            
            if (valik == "1")
            {
                ulesanded.retseptid();
            }
            else if (valik == "2")
            {
                ulesanded.retseptilistiavamine();
            }
            else if (valik == "3")
            {
                ulesanded.KoostisosadFail();
            }
            else if (valik == "4")
            {
                ulesanded.KoostisOsadelugemine();   
            }
            else if (valik == "5")
            {
                ulesanded.Koostisosademuutmine("KoostisOsad.txt");
            }
            else if (valik == "6")
            {
                ulesanded.Otsing("KoostisOsad.txt");
            }
            else if (valik == "7")
            {
                ulesanded.Koostisosadesalvestamine("KoostisOsad.txt");
            }
            else if (valik == "8")
            {
                menuUlesanne.MenuuUlesanne();
            }
            else
            {
                Console.WriteLine("viga");
            }

Näited:

1. Meetodi allkiri (Signature)

//  pääsutase  modifikaator  tagastustüüp  nimi      parameetrid
    public     static        int           Liida     (int a, int b)
{
    return a + b;
}

// Näited erinevate pääsutasemetega
public    static void AvalikMeetod()  { }   // kõigile nähtav
private   static void Privaatne()    { }   // ainult sees klassis
protected static void Kaitstud()     { }   // ainult alamklassides
internal  static void Sisemine()     { }   // ainult projektis

2. Parameetrid vs Argumendid


// PARAMEETRID – meetodi definitsioonis
static void Tervita(string nimi, int vanus)   // nimi, vanus = parameetrid
{
    Console.WriteLine($"{nimi} on {vanus} aastane");
}

// ARGUMENDID – meetodi kutsumisel
string kasutaja = "Mari";
int aasta = 25;

Tervita(kasutaja, aasta);       // kasutaja, aasta = argumendid
Tervita("Jaan", 30);            // otse väärtused = argumendid

3. Väärtuse ja viitega edastamine

// VÄÄRTUSTÜÜP – koopia edastatakse, originaal ei muutu
static void MuudaArvu(int arv)
{
    arv = 999;          // muudab ainult koopiat
}

int x = 10;
MuudaArvu(x);
Console.WriteLine(x);  // 10 – originaal muutumata!

// REF – originaal muutub
static void MuudaRef(ref int arv)
{
    arv = 999;
}

int y = 10;
MuudaRef(ref y);
Console.WriteLine(y);  // 999 ✅

// OUT – meetod peab omistama väärtuse
static void JagaKaheks(int arv, out int osa1, out int osa2)
{
    osa1 = arv / 2;
    osa2 = arv - osa1;
}

JagaKaheks(10, out int a, out int b);
Console.WriteLine($"{a}, {b}");     // 5, 5

// VIITETÜÜP – objekt muutub
static void LisaNimekiri(List<string> nimekiri, string nimi)
{
    nimekiri.Add(nimi);     // originaal muutub!
}

var nimed = new List<string> { "Mari" };
LisaNimekiri(nimed, "Jaan");
Console.WriteLine(nimed.Count);     // 2 ✅

4. Eritüüpi meetodid

Async / Await

// Asünkroonne meetod
static async Task<string> LaeAndmed(string url)
{
    using HttpClient client = new HttpClient();
    string sisu = await client.GetStringAsync(url);
    return sisu;
}

// Kutsumine
static async Task Main()
{
    string andmed = await LaeAndmed("https://example.com");
    Console.WriteLine(andmed);
}

Lühivormid (Expression body)

// Pikk versioon
static int Ruut(int x)
{
    return x * x;
}

// Lühike versioon =>
static int Ruut(int x)          => x * x;
static bool OnPaaris(int x)     => x % 2 == 0;
static string Tervita(string n) => $"Tere, {n}!";
static void Prindi(string t)    => Console.WriteLine(t);

Laiendusmeetodid

// Laiendame string tüüpi
static class StringLaiendused
{
    public static bool OnNumber(this string tekst)
    {
        return int.TryParse(tekst, out _);
    }

    public static string Pööratud(this string tekst)
    {
        char[] tähed = tekst.ToCharArray();
        Array.Reverse(tähed);
        return new string(tähed);
    }
}

// Kasutamine
Console.WriteLine("123".OnNumber());       // True
Console.WriteLine("abc".OnNumber());       // False
Console.WriteLine("Tere".Pööratud());      // ereT

Lokaalsed funktsioonid

static void ArvutaHind(double hind, int kogus)
{
    double lõppHind = Arvuta(hind, kogus);      // kasutab lokaalset funktsiooni
    Console.WriteLine($"Kokku: {lõppHind}€");

    // Lokaalne funktsioon – ainult siin nähtav
    double Arvuta(double h, int k)
    {
        double allahindlus = k > 10 ? 0.1 : 0;
        return h * k * (1 - allahindlus);
    }
}

ArvutaHind(5.99, 12);   // Kokku: 64.692€

5. Main meetod – sisenemispunkt

// Klassikaline versioon
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Tere maailm!");
    }
}

// Käsurea argumendid
static void Main(string[] args)
{
    foreach (string arg in args)
        Console.WriteLine($"Argument: {arg}");
}

// C# 9.0+ top-level (lihtsustatud)
Console.WriteLine("Tere maailm!");  // Main genereeritakse automaatselt

// Async Main
static async Task Main(string[] args)
{
    await Task.Delay(1000);
    Console.WriteLine("Valmis!");
}

6. Tagastusväärtused ja ref return

// Mitu väljumispunkti
static string Hinne(int punktid)
{
    if (punktid >= 90) return "A";
    if (punktid >= 80) return "B";
    if (punktid >= 70) return "C";
    return "F";                         // alati peab return olema!
}

// ref return – tagastab viite
static ref int LeiaMax(ref int a, ref int b)
{
    if (a > b) return ref a;
    return ref b;
}

int x = 10, y = 20;
ref int max = ref LeiaMax(ref x, ref y);
max = 999;                              // muudab originaalmuutujat!
Console.WriteLine(y);                  // 999