8-bo‘lim

Metodlar

Metod e'lon qilish, parametr va qaytariladigan qiymat, ixtiyoriy va nomlangan argumentlar, ref, out va in, params, ortiqcha yuklash va lokal funksiyalar.

🕑 16 daqiqa o‘qish 📄 850 so‘z 👁 1 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Oddiy metod
  2. Qiymat qaytaruvchi metod
  3. Ixtiyoriy parametrlar
  4. Nomlangan argumentlar
  5. ref, out va in
  6. out - metod natijani o'zgaruvchiga yozadi
  7. ref - mavjud qiymatni o'zgartiradi
  8. Kortej qaytarish
  9. params - istalgancha argument
  10. Ortiqcha yuklash
  11. Lokal funksiyalar
  12. Metod nomlash qoidalari
  13. Xulosa

Metod - nom berilgan kod bo'lagi. U bir ishni bajaradi va kerak bo'lganda chaqiriladi. Kodni takrorlamaslikning asosiy vositasi.

Oddiy metod #

CSHARP
Salomlash("Husanboy");
Salomlash("Malika");

void Salomlash(string ism)
{
    Console.WriteLine($"Assalomu alaykum, {ism}!");
}
Natija
Assalomu alaykum, Husanboy!
Assalomu alaykum, Malika!
Metod pastda turibdi, lekin yuqorida chaqirilyapti

Yuqori darajali ko'rsatmalarda metod lokal funksiya bo'ladi va uni e'lon qilinishidan oldin chaqirish mumkin.

Kompilyator butun faylni o'qib chiqadi, shuning uchun tartib muhim emas. Bu odatiy amaliyot: avval asosiy mantiq, pastda yordamchi metodlar.

Qiymat qaytaruvchi metod #

CSHARP
int natija = Qoshish(7, 5);
Console.WriteLine($"7 + 5 = {natija}");
Console.WriteLine($"Kvadrat: {Kvadrat(6)}");

int Qoshish(int a, int b)
{
    return a + b;
}

int Kvadrat(int son) => son * son;
Natija
7 + 5 = 12
Kvadrat: 36

void - hech narsa qaytarmaydi. Boshqa har qanday tur - shu turdagi qiymat qaytariladi.

Ikkinchi metod ifoda tanasi (=>) bilan yozilgan. Metod bitta ifodadan iborat bo'lsa, bu qisqaroq va o'qish osonroq.

Ixtiyoriy parametrlar #

CSHARP
using System.Globalization;

Console.WriteLine(Hisobla(100));
Console.WriteLine(Hisobla(100, 0.2m));
Console.WriteLine(Hisobla(100, 0.2m, 10));

string Hisobla(decimal narx, decimal chegirma = 0.1m, decimal yetkazish = 0)
{
    decimal yakuniy = narx * (1 - chegirma) + yetkazish;
    return string.Format(CultureInfo.InvariantCulture,
        "Narx {0}, chegirma {1:P0} -> {2}", narx, chegirma, yakuniy);
}
Natija
Narx 100, chegirma 10 % -> 90.0
Narx 100, chegirma 20 % -> 80.0
Narx 100, chegirma 20 % -> 90.0

Ixtiyoriy parametrlar oxirida turishi kerak - majburiylaridan keyin.

0.2 emas, 0.2m

Chaqiruvda 0.2m deb yozilganiga e'tibor bering. 0.2 o'z-o'zidan double hisoblanadi va uni decimal parametrga berib bo'lmaydi:

Natija
error CS1503: Argument 2: cannot convert from 'double' to 'decimal'

Bu 3-bo'limdagi qoidaning amaldagi ko'rinishi: pul bilan ishlaganda har bir kasr literaliga m qo'shing.

Nomlangan argumentlar #

Argument ko'p bo'lganda, nomini yozish kodni ancha tushunarli qiladi:

CSHARP
using System.Globalization;

Console.WriteLine(Hisobla(100, yetkazish: 15));
Console.WriteLine(Hisobla(narx: 200, chegirma: 0.25m));

string Hisobla(decimal narx, decimal chegirma = 0.1m, decimal yetkazish = 0)
{
    decimal yakuniy = narx * (1 - chegirma) + yetkazish;
    return string.Format(CultureInfo.InvariantCulture,
        "Yakuniy: {0}", yakuniy);
}
Natija
Yakuniy: 105.0
Yakuniy: 150.00

Birinchi chaqiruvda chegirma o'tkazib yuborildi - u sukut qiymatini oldi, yetkazish esa nom bilan berildi.

Nomlangan argument qachon kerak

Chaqiruvga qarab ma'nosi tushunarsiz bo'lsa:

CSHARP
Yuborish("xat matni", true, false, true);       // nima bu bayroqlar?
Yuborish("xat matni", shoshilinch: true, nusxa: false, saqlash: true);

Ikkinchi qator o'zini o'zi tushuntiradi. bool argumentlar uchun bu deyarli har doim tavsiya etiladi.

ref, out va in #

Odatda argument nusxa bo'lib uzatiladi. Bu kalit so'zlar shuni o'zgartiradi.

out - metod natijani o'zgaruvchiga yozadi #

CSHARP
if (int.TryParse("42", out int son))
{
    Console.WriteLine($"O'qildi: {son}");
}

Bolish(17, 5, out int butun, out int qoldiq);
Console.WriteLine($"17 / 5 = {butun}, qoldiq {qoldiq}");

void Bolish(int a, int b, out int natija, out int qoldiq)
{
    natija = a / b;
    qoldiq = a % b;
}
Natija
O'qildi: 42
17 / 5 = 3, qoldiq 2

out parametrga metod ichida albatta qiymat berilishi kerak - aks holda kompilyator xato beradi.

ref - mavjud qiymatni o'zgartiradi #

CSHARP
int a = 5;
int b = 9;

Console.WriteLine($"Almashtirishdan oldin: a={a}, b={b}");
Almashtir(ref a, ref b);
Console.WriteLine($"Keyin:                 a={a}, b={b}");

void Almashtir(ref int x, ref int y)
{
    (x, y) = (y, x);
}
Natija
Almashtirishdan oldin: a=5, b=9
Keyin:                 a=9, b=5
Kalit so'zChaqirishdan oldin qiymatMetod ichida
(yo'q)KerakNusxa o'zgaradi
refKerakAslini o'zgartiradi
outKerak emasQiymat berish majburiy
inKerakO'zgartirib bo'lmaydi
ref va out ni kamroq ishlating

Ular kerakli vositalar, lekin kodni tushunish qiyinlashtiradi: metod chaqiruviga qarab o'zgaruvchingiz o'zgarib qolishi ko'rinmaydi.

Zamonaviy C# da ko'pincha yaxshiroq yechim bor:

  • Bir nechta qiymat qaytarish kerakmi - kortej ishlating;
  • "Bo'ldimi yoki yo'qmi" kerakmi - bool qaytarib, natijani out ga yozing (bu TryParse uslubi, u qabul qilingan).

Kortej bilan yuqoridagi bo'lish metodi ancha toza chiqadi.

Kortej qaytarish #

CSHARP
(int butun, int qoldiq) = Bolish(17, 5);
Console.WriteLine($"17 / 5 = {butun}, qoldiq {qoldiq}");

var natija = Bolish(20, 3);
Console.WriteLine($"20 / 3 = {natija.butun}, qoldiq {natija.qoldiq}");

(int butun, int qoldiq) Bolish(int a, int b) => (a / b, a % b);
Natija
17 / 5 = 3, qoldiq 2
20 / 3 = 6, qoldiq 2

Bu out dan ancha qulay: natija nomlangan, chaqiruv toza ko'rinadi.

params - istalgancha argument #

CSHARP
Console.WriteLine(Yigindi());
Console.WriteLine(Yigindi(5));
Console.WriteLine(Yigindi(1, 2, 3, 4, 5));

int Yigindi(params int[] sonlar)
{
    int jami = 0;
    foreach (int son in sonlar)
    {
        jami += son;
    }
    return jami;
}
Natija
0
5
15

Console.WriteLine ning o'zi ham shunday ishlaydi - shuning uchun unga istalgancha argument berish mumkin.

Ortiqcha yuklash #

Bir xil nomli, lekin turli parametrli metodlar:

CSHARP
Console.WriteLine(Geometriya.Maydon(5));
Console.WriteLine(Geometriya.Maydon(4, 6));
Console.WriteLine(Geometriya.Maydon("kvadrat", 3));

static class Geometriya
{
    public static int Maydon(int tomon) => tomon * tomon;
    public static int Maydon(int eni, int boyi) => eni * boyi;
    public static string Maydon(string nom, int tomon) =>
        $"{nom}: {tomon * tomon}";
}
Natija
25
24
kvadrat: 9

Kompilyator argumentlarga qarab qaysi metodni chaqirishni o'zi aniqlaydi.

Lokal funksiyani ortiqcha yuklab bo'lmaydi

Yuqoridagi metodlar nega sinf ichiga qo'yildi? Chunki ularni shu bobdagi boshqa misollar kabi to'g'ridan-to'g'ri yozsangiz, kod kompilyatsiya qilinmaydi:

Natija
error CS0128: A local variable or function named 'Maydon'
is already defined in this scope

Ortiqcha yuklash faqat sinf a'zolari uchun ishlaydi. Lokal funksiyalar oddiy o'zgaruvchilar kabi qaraladi: bitta qamrovda bir xil nomli ikkita bo'la olmaydi.

Bu 1-bobda aytilgan gapning sababi: class va static shakli eskirgani uchun emas, ba'zi imkoniyatlar faqat unda mavjudligi uchun kerak. Sinflar bilan keyingi bobda to'liq tanishamiz.

Ortiqcha yuklash va ixtiyoriy parametr birga xavfli
CSHARP
Chiqarish.Yoz("salom");

static class Chiqarish
{
    public static void Yoz(string matn) =>
        Console.WriteLine($"A: {matn}");
    public static void Yoz(string matn, bool qalin = false) =>
        Console.WriteLine($"B: {matn}");
}
Natija
A: salom

Ikkala metod ham bitta argument bilan chaqirilishi mumkin. Kompilyator xato bermaydi - u aniqroq mos kelganini tanlaydi, ya'ni birinchisini.

Natijada siz ikkinchisini kutgan bo'lsangiz, buni topish juda qiyin. Shuning uchun ularni birga ishlatmaslikka harakat qiling.

Lokal funksiyalar #

Metod ichida yordamchi metod e'lon qilish mumkin:

CSHARP
Console.WriteLine(Faktorial(5));
Console.WriteLine(Faktorial(0));

int Faktorial(int n)
{
    if (n < 0)
    {
        throw new ArgumentException("Manfiy son bo'lmasin", nameof(n));
    }

    return Hisobla(n);

    // faqat shu metod ichida ko'rinadi
    int Hisobla(int son) => son <= 1 ? 1 : son * Hisobla(son - 1);
}
Natija
120
1

Tashqi metod argumentni tekshiradi, ichkisi esa tekshiruvsiz rekursiya qiladi. Bu keng tarqalgan naqsh.

nameof nima qiladi

nameof(n) - o'zgaruvchi nomini satr sifatida beradi, ya'ni "n".

Nega shunchaki "n" deb yozmaslik kerak? Chunki keyin parametr nomini o'zgartirsangiz, nameof avtomatik yangilanadi, oddiy satr esa eski nom bilan qolib ketadi va xato xabari chalg'ituvchi bo'ladi.

Metod nomlash qoidalari #

QoidaMisol
Katta harfdan boshlanadi (PascalCase)HisoblaYigindi
Fe'l bilan boshlanadiYoz, Hisobla, Tekshir
bool qaytarsa savol shaklidaBoshmiTekshir, MavjudmiTekshir
Parametrlar kichik harfdan (camelCase)int talabaSoni
Metod bitta ish qilsin

Yaxshi metodning belgisi - nomini qiyinchiliksiz qo'ya olish.

Agar nom o'ylab topolmayotgan bo'lsangiz yoki nomda "va" so'zi paydo bo'lsa (OqiVaSaqla), metod ikki ish qilyapti - uni ikkiga bo'ling.

Uzunligi uchun qat'iy qoida yo'q, lekin ekranga sig'masa - bu ogohlantirish belgisi.

Amaliy topshiriq
  1. Ikkita sonni qabul qilib, kattasini qaytaruvchi metod yozing.
  2. Uni ifoda tanasi (=>) bilan qayta yozing.
  3. Ixtiyoriy parametrli metod yarating va uni uch xil chaqiring.
  4. Nomlangan argument bilan chaqirib ko'ring.
  5. out bilan bo'linma va qoldiqni qaytaruvchi metod yozing.
  6. Xuddi shu metodni kortej bilan qayta yozing va solishtiring.
  7. ref bilan ikki o'zgaruvchi qiymatini almashtiring.
  8. params bilan istalgancha sonning o'rtachasini hisoblang.
  9. Bir nomli uchta metodni turli parametrlar bilan yozing.
  10. Lokal funksiya bilan rekursiv Fibonachchi sonini hisoblang.

Xulosa #

  • Metod bitta ish qilsin; nom qo'yish qiyin bo'lsa - uni bo'ling.
  • Bitta ifodadan iborat metodni => bilan qisqartiring.
  • Ixtiyoriy parametrlar oxirida turadi; nomlangan argumentlar chaqiruvni tushunarli qiladi.
  • out - metod natijani yozadi, ref - mavjud qiymatni o'zgartiradi, in - o'zgartirishni taqiqlaydi.
  • Bir nechta qiymat qaytarish uchun out emas, kortej qulayroq.
  • params istalgancha argument qabul qiladi.
  • Ortiqcha yuklash va ixtiyoriy parametrni birga ishlatmang.
  • nameof nomni satrga aylantiradi va qayta nomlashda yangilanadi.

Keyingi bo'limda sinflar va obyektlarga o'tamiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.