1. Giriş
Artıq belə kod yaza bilirsən:
switch (color)
{
case "red":
Console.WriteLine("Dayan!");
break;
case "yellow":
Console.WriteLine("Gözlə...");
break;
case "green":
Console.WriteLine("Gedə bilərsən!");
break;
default:
Console.WriteLine("Bu nə rəngdir?");
break;
}
Bəs əgər biz dəyişənə daxil olan parametrə görə fərqli dəyər vermək istəsək, məsələn, funksiyadan ədədə əsaslanan string qaytarmaq istəsək? switch-expressionlər çıxmamışdan əvvəl belə şeylər yazmalı idik:
string meaning;
switch (number)
{
case 42:
meaning = "Həyatın, kainatın və ümumiyyətlə hər şeyin əsas sualının cavabı";
break;
case 7:
meaning = "Uğurlu rəqəm";
break;
default:
meaning = "Adi rəqəm";
break;
}
XXI əsrin dili üçün bir az köhnə görünür, düzdür? İstəyirsən ki, dəyəri birbaşa qaytarasan, necə ki, funksional dillərdə olur.
Bax, burada switch-expressionlər meydana çıxır — C#-ın ən gözəl (və təzə) imkanlarından biri, 8.0 versiyasından başlayaraq.
2. switch-expressionlər: sarılmaq istədiyin sintaksis
Müqayisə edək: operator və expression
Klassik switch — bu bir statement ("operator"), switch-expression isə expression-dır, yəni dəyər hesablayır və onu birbaşa dəyişənə vermək və ya metoddan qaytarmaq olar.
switch-expression-un strukturu:
var result = value switch
{
pattern1 => expression1,
pattern2 => expression2,
_ => defaultExpression // "alt xətt" - "əks halda"
};
Məsələn:
int number = 42;
string meaning = number switch
{
42 => "Həyatın, kainatın və ümumiyyətlə hər şeyin əsas sualının cavabı",
7 => "Uğurlu rəqəm",
_ => "Adi rəqəm"
};
Console.WriteLine(meaning); // => Həyatın, kainatın və ümumiyyətlə hər şeyin əsas sualının cavabı
Hər şey qısa, oxunaqlı, kod "portyankası" yoxdur, bir dənə də break; yoxdur.
Diqqət et: alt xətt _ — "qalan bütün halları tutmaq" üçündür, default-un analoqudur.
3. switch-expressionlər və pattern-lər: necə işləyirlər
Əsl əyləncə burada başlayır. switch-expressionlərdə təkcə adi dəyərlər yox, həm də pattern-lər istifadə etmək olar: intervala görə, tipə görə, obyektin property-lərinə görə yoxlama, deconstruction (obyekti hissələrə ayırmaq), hətta combinatorial patterns (and, or, not).
switch-expression-da pattern nümunələri
Konstant pattern-lər
Yuxarıda etdiyimiz kimi: 42, 7 və s. ilə müqayisə.
Interval və müqayisələr
int age = 17;
string category = age switch
{
< 18 => "Yetkinlik yaşına çatmamış",
>= 18 and <= 65 => "Böyük",
> 65 => "Yaşlı insan",
_ => "Naməlum yaş kateqoriyası"
};
Console.WriteLine(category);
Yeri gəlmişkən, fikir ver — bir neçə şərti birlikdə istifadə etmək olar! C# getdikcə daha ifadəli olur.
Tip pattern-ləri (Type Patterns)
Tutaq ki, bizdə fərqli tipdə ola bilən obyekt var (məsələn, object value;). Fərqli tipləri belə işləyə bilərik:
object value = 3.14;
string description = value switch
{
int i => $"Tam ədəd: {i}",
double d => $"Ondalık ədəd: {d:F2}",
string s => $"Bu stringdir: '{s}'",
null => "null!",
_ => "Başqa bir şey"
};
Console.WriteLine(description); // => Ondalık ədəd: 3.14
Əlaqəli pattern-lər (Property Patterns və Positional Patterns)
C# 8 və sonrası property dəyərlərini birbaşa switch-expression-da yoxlamağa imkan verir.
Obyekt nümunəsi
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
User user = new User { Name = "Anna", Age = 17 };
string welcome = user switch
{
{ Age: < 18 } => $"Salam, {user.Name}! Sən yeniyetməsən.",
{ Age: >= 18 and <= 65 } => $"Salam, {user.Name}! Böyüklük gözəldir.",
{ Age: > 65 } => $"Xoş gəlmisən, {user.Name}! Səni həmişə görməyə şadıq.",
_ => "Naməlum yaş"
};
Console.WriteLine(welcome);
Burada figurli mötərizədə { Age: < 18 } — property pattern-dir, yəni bütün obyekt yox, yalnız property yoxlanılır.
4. Yeni pattern-lər C# 11-14
C# qısa və çevik olmağa çalışır. Son zamanlar combinatorial patterns: and, or, not əlavə olunub, positional pattern-lər də yaxşılaşıb. Gəlin baxaq.
Logical pattern-lər: and, or, not
Şərtləri matlogika kimi birləşdirə bilərsən!
int temperature = 25;
string result = temperature switch
{
< 0 => "Don!",
>= 0 and < 20 => "Sərin",
>= 20 and < 30 => "Rahat",
>= 30 or <= -30 => "Ekstremal!",
_ => "Qəribə temperatur"
};
Əgər istisna etmək istəyirsənsə, buyur:
int score = 80;
string grade = score switch
{
>= 90 => "Əla",
>= 60 and not >= 90 => "Yaxşı",
_ => "Pis"
};
Dekonstruksiya (Positional Patterns)
Əgər struktur və ya record varsa və deconstruction dəstəkləyirsə, C# obyektləri birbaşa switch-expression-da ayırmağa imkan verir:
public record Point(int X, int Y);
Point p = new Point(10, 20);
string desc = p switch
{
(0, 0) => "Başlanğıc nöqtəsi",
(var x, 0) => $"X oxunda, X={x}",
(0, var y) => $"Y oxunda, Y={y}",
(var x, var y) when x == y => $"Diaqonalda: {x}",
_ => $"Nöqtədə ({p.X}, {p.Y})"
};
Console.WriteLine(desc); // => Nöqtədə (10, 20)
5. switch-expressionləri nə vaxt və niyə istifadə etməli
Müasir C#-da switch-expressionlər təkcə dəbli "fitcha" deyil, həqiqətən kodu qısa, test və dəstək üçün rahat etmək üçün real yoldur. Bu xüsusilə parser, komanda handler-ləri, biznes-logika, qayda konfiqurasiyası və s. yazanda vacibdir — yəni icranı müxtəlif şərtlərə görə (yalnız dəyərə yox, tipə, intervala, property-lərə, kombinasiyalara görə) bölmək lazım olanda.
Müsahibədə
- İstifadəçidən fərqli cavab variantlarını necə işləyərdin?
- Funksiyanın dəyərini həm tipə, həm də dəyərə görə necə qaytarmaq olar?
- Yeni qaydaları əlavə etməyi if-else yığını olmadan necə rahat edərdin?
Pattern-lərlə switch-expression göstər! Bu dərhal yeni imkanları bildiyini və yaxşı kod stilinə sahib olduğunu göstərir.
Cədvəl: switch-operatoru və switch-expression müqayisəsi
| Xüsusiyyət | switch statement | switch expression |
|---|---|---|
| Tip | operator (statement) | expression (expression) |
| break istifadəsi | mütləqdir | lazım deyil |
| Dəyər qaytara bilər | yalnız dəyişənlə | bəli, birbaşa dəyər qaytarır |
| Pattern istifadə edə bilər | qismən | tam (type, property və s.) |
| Tələ | break-i unutmaq olar | bütün yollar dəyər qaytarmalıdır |
6. Tipik səhvlər və xırda oyunlar
- Yeni başlayanlar tez-tez switch-operatoru ("statement") və switch-expression ("expression") fərqində çaşırlar. Məsələn, unudurlar ki, switch-expression-da break; lazım deyil və bütün budaqlar mütləq dəyər qaytarmalıdır.
- _ budağını unutsaq, compiler xəbər verir: "bəs heç biri uyğun gəlməsə?".
- switch-expression-da goto istifadə etmək olmaz (şükür ki!).
- Əgər şərt təkrarlanırsa (məsələn, iki eyni pattern), compiler də buna icazə verməyəcək.
- switch-expression-dan qaytarılan dəyərin tipinə diqqət et: onu təyin etdiyin dəyişənin tipi ilə uyğun olmalıdır.
GO TO FULL VERSION