5-bo‘lim
Shartlar va namuna moslashtirish
if va else, shartli operator, switch ifodasi, is operatori, tur va xossa namunalari, mantiqiy namunalar va ro'yxat namunalari.
Ushbu bo‘lim mundarijasi
Shartlar har qanday dasturning asosi. C# da ular oddiy if dan
boshlanadi, lekin namuna moslashtirish (pattern matching) ni
qo'shganda ancha kuchli vositaga aylanadi.
if, else if, else #
int ball = 87;
if (ball >= 90)
{
Console.WriteLine("A'lo");
}
else if (ball >= 70)
{
Console.WriteLine("Yaxshi");
}
else if (ball >= 60)
{
Console.WriteLine("Qoniqarli");
}
else
{
Console.WriteLine("Qoniqarsiz");
}
Yaxshi
C# bitta ko'rsatma uchun { } ni talab qilmaydi:
if (ball >= 70)
Console.WriteLine("Yaxshi");
Bu ishlaydi, lekin xavfli odat. Keyin ikkinchi qatorni qo'shsangiz, u shartdan tashqarida qoladi va buni sezish qiyin.
Bu haqiqiy va mashhur xato: 2014-yilda Apple tizimidagi jiddiy
xavfsizlik zaifligi aynan qavssiz if dan keyin ikkinchi qator
qo'shilgani sababli yuzaga kelgan.
Qoida: har doim qavs qo'ying, hatto bitta qator bo'lsa ham.
Mantiqiy amallar #
int yosh = 20;
bool talabami = true;
Console.WriteLine(yosh >= 18 && talabami);
Console.WriteLine(yosh < 18 || talabami);
Console.WriteLine(!talabami);
True
True
False
| Amal | Ma'nosi |
|---|---|
&& | VA - ikkalasi ham rost bo'lsa |
|| | YOKI - kamida bittasi rost bo'lsa |
! | EMAS - teskarisi |
&& va || qisqa tutashuv bilan ishlaydi: natija ma'lum
bo'lganda o'ng tomon umuman hisoblanmaydi.
string? ism = null;
if (ism != null && ism.Length > 3)
{
Console.WriteLine("Uzun ism");
}
else
{
Console.WriteLine("Ism yo'q yoki qisqa");
}
Ism yo'q yoki qisqa
Birinchi shart false bo'lgani uchun ism.Length umuman
chaqirilmadi - aks holda dastur qulardi. Shu sababli tekshiruvlar
tartibi muhim: avval null ni tekshiring, keyin qolganini.
Shartli operator #
Qisqa tanlov uchun ?: ishlatiladi:
int ball = 87;
string natija = ball >= 60 ? "o'tdi" : "o'tmadi";
Console.WriteLine($"Talaba {natija}");
int a = 15, b = 23;
Console.WriteLine($"Kattasi: {(a > b ? a : b)}");
Talaba o'tdi
Kattasi: 23
switch ifodasi #
Zamonaviy C# da switch qiymat qaytaradi. Bu eski switch
ko'rsatmasidan ancha qulay:
int kun = 3;
string nom = kun switch
{
1 => "Dushanba",
2 => "Seshanba",
3 => "Chorshanba",
4 => "Payshanba",
5 => "Juma",
6 or 7 => "Dam olish kuni",
_ => "Noma'lum"
};
Console.WriteLine(nom);
Chorshanba
| Belgi | Ma'nosi |
|---|---|
=> | Shu holat uchun qaytariladigan qiymat |
or | Bir nechta qiymatni birlashtiradi |
_ | Qolgan barcha holatlar |
Eski switch ko'rsatmasida unutilgan holat jimgina o'tib ketardi.
switch ifodasi esa mos holat topilmasa
SwitchExpressionException tashlaydi.
Ya'ni xato yashirinmaydi - darhol ko'rinadi. Shuning uchun _ ni
faqat haqiqatan kerak bo'lganda qo'ying.
Diapazon namunalari #
Sonni oraliqqa tekshirish uchun switch juda qulay:
int ball = 87;
string baho = ball switch
{
>= 90 => "A'lo",
>= 70 => "Yaxshi",
>= 60 => "Qoniqarli",
_ => "Qoniqarsiz"
};
Console.WriteLine($"{ball} ball -> {baho}");
87 ball -> Yaxshi
Bu bobning boshidagi if/else if zanjiri bilan bir xil ish qiladi,
lekin ancha qisqa va o'qish oson.
is operatori va tur namunalari #
is qiymatning turini tekshiradi va darhol o'zgaruvchiga yozadi:
object[] narsalar = [42, "salom", 3.14, true, 'A'];
foreach (object narsa in narsalar)
{
string tavsif = narsa switch
{
int son => $"butun son: {son}",
string matn => $"satr, uzunligi {matn.Length}",
double kasr => $"kasr son (yaxlitlangan): {Math.Round(kasr)}",
bool mantiq => $"mantiqiy: {mantiq}",
_ => $"boshqa tur: {narsa.GetType().Name}"
};
Console.WriteLine(tavsif);
}
butun son: 42
satr, uzunligi 5
kasr son (yaxlitlangan): 3
mantiqiy: True
boshqa tur: Char
Har bir holatda tur tekshirildi va qiymat mos turdagi o'zgaruvchiga yozildi - alohida aylantirish kerak bo'lmadi.
Mantiqiy namunalar #
and, or va not namunalarni birlashtiradi:
int[] sonlar = [-5, 0, 7, 42, 150];
foreach (int son in sonlar)
{
string turkum = son switch
{
< 0 => "manfiy",
0 => "nol",
> 0 and < 10 => "kichik",
>= 10 and <= 99 => "o'rta",
_ => "katta"
};
Console.WriteLine($"{son,4} -> {turkum}");
}
-5 -> manfiy
0 -> nol
7 -> kichik
42 -> o'rta
150 -> katta
Ro'yxat namunalari #
C# 11 dan massiv va ro'yxat tuzilishini ham tekshirish mumkin:
int[][] toplamlar =
[
[],
[7],
[1, 2],
[1, 2, 3, 4, 5]
];
foreach (int[] toplam in toplamlar)
{
string tavsif = toplam switch
{
[] => "bo'sh",
[int bitta] => $"bitta element: {bitta}",
[int birinchi, int ikkinchi] => $"ikkita: {birinchi} va {ikkinchi}",
[int bosh, .. int[] qolgan] =>
$"boshi {bosh}, yana {qolgan.Length} ta",
};
Console.WriteLine(tavsif);
}
bo'sh
bitta element: 7
ikkita: 1 va 2
boshi 1, yana 4 ta
.. belgisi "qolgan hammasi" degani. Bu juda kuchli vosita: ro'yxatni
qismlarga ajratish uchun indekslar bilan ishlash kerak emas.
Xossa namunalari #
Obyektning ichidagi qiymatni ham tekshirish mumkin. Buni 9-bo'limda sinflar bilan tanishgach to'liq ishlatamiz, hozir esa oddiy misol:
(string shahar, int aholi)[] joylar =
[
("Namangan", 626000),
("Toshkent", 2900000),
("Chust", 68000)
];
foreach (var joy in joylar)
{
string turkum = joy switch
{
{ aholi: > 1000000 } => "megapolis",
{ aholi: > 100000 } => "yirik shahar",
_ => "kichik shahar"
};
Console.WriteLine($"{joy.shahar,-10} {turkum}");
}
Namangan yirik shahar
Toshkent megapolis
Chust kichik shahar
Namunalar yuqoridan pastga tekshiriladi va birinchi mos kelgani ishlaydi.
Yuqoridagi misolda > 100000 shartini birinchi qo'ysangiz, Toshkent
ham "yirik shahar" bo'lib qolardi - chunki 2.9 million ham 100 mingdan
katta.
Qoida: eng tor shartni yuqoriga, eng kengini pastga qo'ying.
Eski switch ko'rsatmasi #
Eski kodda uchraydi, shuning uchun tanish bo'lishi kerak:
int kun = 6;
switch (kun)
{
case 1:
case 2:
case 3:
case 4:
case 5:
Console.WriteLine("Ish kuni");
break;
case 6:
case 7:
Console.WriteLine("Dam olish");
break;
default:
Console.WriteLine("Noma'lum");
break;
}
Dam olish
| switch ko'rsatmasi | switch ifodasi | |
|---|---|---|
| Qiymat qaytaradimi | Yo'q | Ha |
break kerakmi | Ha, majburiy | Yo'q |
| Yozilishi | Uzun | Qisqa |
| Qachon | Bir nechta amal bajarilganda | Qiymat tanlanganda |
- Ball bo'yicha baho beruvchi
if/else ifzanjirini yozing. - Xuddi shu mantiqni
switchifodasi bilan qayta yozing. - Qavssiz
ifxatosini o'zingiz yaratib ko'ring. - Qisqa tutashuv nima uchun kerakligini
nullmisolida tushuntiring. - Shartli operator (
?:) bilan ikki sondan kattasini toping. objectmassivi ustida tur namunalarini qo'llang.- Sonni beshta turkumga ajratuvchi mantiqiy namuna yozing.
- Ro'yxat namunasi bilan bo'sh, bitta va ko'p elementli massivlarni ajrating.
- Namunalar tartibini ataylab buzib, natija qanday o'zgarishini ko'ring.
- Eski
switchda bittabreakni olib tashlab, kompilyator nima deyishini ko'ring.
Xulosa #
ifdan keyin har doim qavs qo'ying - bu mashhur xavfsizlik xatosining sababi bo'lgan.&&va||qisqa tutashuv qiladi:nulltekshiruvini birinchi yozing.switchifodasi qiymat qaytaradi,breaktalab qilmaydi va qamrab olinmagan holatda istisno tashlaydi.- Diapazon namunalari (
>= 90 =>) uzunif/else ifzanjirini almashtiradi. - Tur namunasi (
int son =>) turni tekshiradi va bir vaqtda o'zgaruvchiga yozadi. and,or,notnamunalarni birlashtiradi.- Ro'yxat namunasi (
[bosh, .. qolgan]) to'plam tuzilishini tekshiradi. - Namunalar yuqoridan pastga tekshiriladi - eng tor shart yuqorida bo'lsin.
Keyingi bo'limda sikllarni o'rganamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.