Wyrażenie Switch w C# Wyjaśnione: Praktyczny przewodnik od Tima Coreya
W świecie programowania w C#, pisanie czystego i łatwego w utrzymaniu kodu jest kluczowym celem. Jednym z nowoczesnych rozwiazan w C# pomagajacych w osiagnieciu tego celu jest wyrazenie switch - kompaktowa i potężna alternatywa dla tradycyjnej instrukcji switch. Chociaż często pomijane, wyrazenia switch upraszczaja zlozona logike rozgalezien, zwlaszcza przy pracy z wzorcami relacyjnymi, dopasowaniem wzorcow i stalymi wzorcami.
Aby lepiej zrozumieć, jak działa ta funkcja oraz jak wypada w porownaniu z tradycyjnymi podejściami, obejrzymy pomocny film Tima Corey'ego. Przez cały swój film na temat "Switch Expressions In C#", Tim analizuje rzeczywiste użycie wyrażeń switch w C#, pokazując, jak pisać lepszy kod z mniejszą ilością linii.
Zanurzmy się w praktyczne wyjaśnienie Tima, które zaczyna się od przykładu z ocenami i prowadzi do bardziej zaawansowanych scenariuszy przy użyciu interfejsów, wzorców typów i oceny obiektów.
Tradycyjne if-else vs. wyrazenie switch
Tim zaczyna od aplikacji konsolowej, gdzie zmienna typu int o nazwie numberGrade zawiera wynik testu, na przykład 85. Celem jest przekształcenie tej wartości numerycznej na odpowiadającą jej literową ocenę, na przykład 'B'. W większości przypadków programiści używaliby serii instrukcji if-else lub instrukcji switch, jak ta:
if (numberGrade >= 90)
letterGrade = "A";
else if (numberGrade >= 80)
letterGrade = "B";
// ...and so on
if (numberGrade >= 90)
letterGrade = "A";
else if (numberGrade >= 80)
letterGrade = "B";
// ...and so on
Chociaż to działa, jest rozwleczone. Z kolei wyrazenia switch w C# oferuja czysta skladnie.
Pisanie wyrazenia switch dla oceniania
Aby zademonstrować wyrazenie switch, Tim przepisuje powyższą logikę używając następującego kodu:
string letterGrade = numberGrade switch
{
>= 90 => "A",
>= 80 => "B",
>= 70 => "C",
>= 60 => "D",
_ => "F"
};
string letterGrade = numberGrade switch
{
>= 90 => "A",
>= 80 => "B",
>= 70 => "C",
>= 60 => "D",
_ => "F"
};
Tutaj slowo kluczowe switch jest używane w nowym kontekście - jako wyrazenie, a nie instrukcja. Oznacza to, że ocenia wartość bezpośrednio i może być przypisane do zmiennej (np. letterGrade).
Ta forma obsługuje wzorce relacyjne (np. >= 90) i wykorzystuje wzorzec odrzutu (_) do obsługi przypadku domyślnego, co odpowiada końcowemu else.
Tim zauważa, że kompilator określa dopasowanie w czasie wykonywania, sprawdzając każde warunki od góry do dołu i wybierając pierwszy wzorzec, który pasuje do wejściowego.
Upraszczanie kodu za pomocą wyrażeń
Według słów Tima, ta nowa składnia "zastępuje całe mnóstwo kodu." Zamiast powtarzać warunki z else if, wyrazenie switch obsługuje wszystko w przejrzystej, zwięzłej strukturze. To upraszcza przepływ sterowania, poprawia czytelność i zmniejsza nadmiar logiki.
Podkreśla, że ta struktura jest szczególnie przydatna podczas mapowania wartości wejściowych na określone wyniki - jak ocenianie, komunikaty o stanie czy transformacja danych.
Używanie dopasowania wzorcow z typami obiektow
Aby zbadac wzorce typow i dopasowanie wzorcow, Tim wprowadza scenariusz z udzialem interfejsu IAnimal. Definiuje trzy klasy - Dog, Cat i Cow - z których kazda implementuje interfejs. Pozwala mu to na utworzenie listy zwierzat, kazde z innymi właściwościami.
interface IAnimal { }
record Dog(string Name) : IAnimal;
record Cat(string Title, string Name) : IAnimal;
record Cow(string Breed) : IAnimal;
interface IAnimal { }
record Dog(string Name) : IAnimal;
record Cat(string Title, string Name) : IAnimal;
record Cow(string Breed) : IAnimal;
Wypelnia liste różnymi instancjami zwierzat i pokazuje, jak użyć dopasowania wzorcow typow do identyfikacji typu obiektu i ekstrakcji danych.
Wyrazenie switch z dopasowaniem wzorcow
Tim pokazuje, jak następujący kod używający if:
if (a is Dog d)
message = $"Dog: {d.Name}";
else if (a is Cat c)
message = $"Cat: {c.Title} {c.Name}";
else if (a is Cow co)
message = $"Cow: {co.Breed}";
else
message = "Unknown animal";
if (a is Dog d)
message = $"Dog: {d.Name}";
else if (a is Cat c)
message = $"Cat: {c.Title} {c.Name}";
else if (a is Cow co)
message = $"Cow: {co.Breed}";
else
message = "Unknown animal";
Można zastepic znacznie bardziej zwiezłym i czytelnym wyrazeniem switch:
string message = a switch
{
Dog d => $"Dog: {d.Name}",
Cat c => $"Cat: {c.Title} {c.Name}",
Cow co => $"Cow: {co.Breed}",
_ => "Unknown animal"
};
string message = a switch
{
Dog d => $"Dog: {d.Name}",
Cat c => $"Cat: {c.Title} {c.Name}",
Cow co => $"Cow: {co.Breed}",
_ => "Unknown animal"
};
To wyrazenie sprawdza typ obiektu i stosuje odpowiednie wyjście na podstawie dopasowanego wzorca. Jeśli nie znaleziono dopasowania, przechodzi do domyślnego wyniku przy użyciu odrzutu _.
Ta funkcja zwieksza funkcjonalność bez utraty przejrzystosci. Dzialanie w czasie wykonywania pozostaje przewidywalne i czytelne.
Opcjonalne zabezpieczenia z użyciem slowa when
Chociaż nie pokazane w przykładzie Tima, wartosc dodania, że wyrazenia switch mogą być rozszeszone przez slowo when, pozwala na zastosowanie opcjonalnego warunku boolean:
int score = 90;
string result = score switch
{
int s when s >= 90 && s <= 100 => "Excellent",
int s when s >= 75 => "Good",
_ => "Needs Improvement"
};
int score = 90;
string result = score switch
{
int s when s >= 90 && s <= 100 => "Excellent",
int s when s >= 75 => "Good",
_ => "Needs Improvement"
};
Tutaj klauzula when pozwala na wlasciwa ocene argumentu, używając bardziej złożonych wyrażeń booleowskich.
Najlepsze praktyki i ostateczne uwagi
Tim podkreśla kluczowa kwestie: choc wyrazenia switch sprawiaja, ze twoj kod staje sie bardziej zwarty, kompaktowe nie zawsze oznacza lepsze. Czasami, zwłaszcza przy skomplikówanej logice lub niejasnych wejsciach, bardziej odpowiednia może być tradycyjna instrukcja switch lub blok if.
Nie musisz używać wyrazenia switch w kazdym przypadku - używaj odpowiedniego narzędzia do zadania. To nie o przystąpieniu do "kultu switcha", jak zartuje Tim. Chodzi o pisanie łatwego w utrzymaniu i zrozumialego kodu w twoim systemie.
Podsumowanie: Dodawanie wyrazeń switch do swojego zestawu narzędzi dewelopera
Wyrazenia switch w C# oferuja nowoczesny, czysty sposob oceny i zwracania wartosci na podstawie wzorców wejściowych, wykorzystując kombinację wzorców stałych, relacyjnych i typowych. Są idealne, jeśli chcesz uprościć logikę, zredukować szablony i poprawić czytelność.
Od oceniania liczby całkowitych po identyfikację obiektów zwierzęcych, następujące przykłady w video Tima Corey'ego video pokazują ich praktyczne zastosowania. Niezależnie od tego, czy tworzysz funkcję do obliczania wyników, obsługujesz wejścia użytkownika, czy pracujesz z przypadkami null i undefined, wyrazenia switch mogą pomóc zaoszczędzić czas, zmniejszyć błędy i ułatwić zarządzanie kodem.
Jak mówi Tim, "Są naprawdę pomocnym narzędziem w twoim zestawie, aby twój kod był prostszy i czystszy - a przy tym nadal tak samo zrozumiały, jeśli nie bardziej."
Jeśli chodzi o poprawę jakości kodu C# i pozostawanie na bieżąco z innowacjami .NET Core, nie pomijaj wyrazeń switch. Wypróbuj je, eksperymentuj w projektach Visual Studio i zobacz, jak bardzo możesz uprościć swoją logikę.
