Zastosowanie własnych delegatów do obliczania różnych wariantów finansowych wynagrodzenia (Netto/Brutto). Student uczy się przekazywać konkretne funkcje przeliczające jako parametry do uniwersalnego procesora list płac.
Budujesz system kadrowo-płacowy dla dużej korporacji, która zatrudnia pracowników na różnych typach umów: o pracę, zlecenie oraz B2B. Każdy typ umowy ma inny algorytm wyliczania kwoty "na rękę" na podstawie kwoty bazowej. Twoim zadaniem jest zdefiniowanie delegata o nazwie "KalkulatorPensji", który przyjmuje kwotę (decimal) i zwraca wynik po potrąceniu podatków. Musisz napisać trzy niezależne metody realizujące te obliczenia dla każdego typu umowy. Następnie zaprojektuj klasę "ProcesorPlac", która posiada metodę WygenerujRaport, przyjmującą kwotę oraz wspomniany delegat. Dzięki takiemu podejściu, Twój procesor nie musi znać skomplikowanych przepisów podatkowych – on po prostu wywołuje przekazaną mu funkcję. Program w konsoli powinien symulować wystawienie trzech pasków płacowych dla tej samej kwoty brutto, pokazując ogromną elastyczność delegatów w biznesie. To zadanie uczy, jak projektować systemy obliczeniowe, które są łatwe do rozbudowy o nowe przepisy prawne bez modyfikacji głównego silnika raportowego. Program kończy pracę wyświetleniem sumy wypłat dla wszystkich przetestowanych wariantów. Precyzja obliczeń finansowych i czytelność kodu są tutaj kluczowe.
Zrozumienie jak działają zdarzenia w interfejsach graficznych poprzez ich ręczną symulację w konsoli. Student uczy się projektować interaktywne komponenty, które powiadamiają inne części systemu o interakcji użytkownika.
Choć pracujesz w konsoli, Twoim zadaniem jest stworzenie klasy "Przycisk", która zachowuje się jak prawdziwy element okna Windows. Klasa ta powinna posiadać publiczne zdarzenie "OnClick". Każdy, kto chce zareagować na kliknięcie (np. klasa "Lampka", która ma się zapalić, lub klasa "Loger", która ma zapisać fakt kliknięcia), musi zasubskrybować to zdarzenie. Twoim wyzwaniem jest zaimplementowanie metody "Kliknij()", która po wywołaniu w konsoli uruchomi wszystkie podpięte funkcje. Aby zadanie było bardziej profesjonalne, użyj standardowego delegata .NET: EventHandler lub Action. Stwórz w Main obiekt przycisku, podepnij do niego dwie różne akcje (wyrażenia lambda) i wywołaj metodę Kliknij() kilka razy. Następnie odepnij jedną z akcji i pokaż, że system nadal działa poprawnie, wykonując tylko pozostałe zadania. Takie podejście uczy projektowania oprogramowania sterowanego zdarzeniami (Event-Driven Programming), co jest fundamentem tworzenia aplikacji mobilnych i desktopowych. Program kończy pracę krótkim podziękowaniem od wszystkich "aktywnych" subskrybentów przycisku. Wykorzystaj kolory konsoli, aby odróżnić reakcje różnych modułów aplikacji.
Zaawansowane filtrowanie kolekcji z wykorzystaniem wyrażeń lambda jako dynamicznych warunków logicznych. Student uczy się pisać generyczne silniki wyszukiwania, które nie wymagają zmiany kodu przy wprowadzaniu nowych kryteriów biznesowych.
Pracujesz nad wyszukiwarką dla sklepu internetowego z elektroniką. Twoja baza zawiera listę obiektów klasy Produkt (pola: Nazwa, Cena, Kategoria, CzyDostepny). Musisz napisać jedną, uniwersalną metodę o nazwie "FiltrujProdukty", która przyjmuje listę oraz delegat Predicate<Produkt>. Twoim zadaniem jest przeprowadzenie serii testów, w których będziesz szukać: produktów z kategorii 'Laptopy' tańszych niż 3000 zł, wszystkich niedostępnych produktów oraz tych, których nazwa zawiera słowo 'Pro'. Każde z tych zapytań musi być zrealizowane jako pojedyncze wyrażenie lambda przekazane do wspomnianej metody. Program powinien wyświetlić wyniki każdego filtrowania w estetyczny sposób, podając liczbę znalezionych pozycji. To zadanie uczy, jak ogromną moc daje łączenie lambd z kolekcjami generycznymi, co jest podstawą pracy z dużymi zbiorami danych. Zwróć uwagę na zwięzłość zapisu – cała logika filtru powinna zmieścić się w jednej linii wywołania. Finalnie podsumuj, jak dużą oszczędność linii kodu daje takie podejście w porównaniu do tradycyjnych pętli. Jest to idealny przykład przygotowujący do nauki zaawansowanego LINQ.
Integracja klasy generującej zdarzenia z klasą rejestrującą je w pamięci. Student uczy się projektować systemy "obserwatorów", gdzie jeden obiekt automatycznie śledzi i dokumentuje aktywność drugiego za pomocą bezpiecznych zdarzeń.
Zaprojektuj system monitorowania temperatury w serwerowni. Stwórz klasę "Termometr", która co sekundę (lub w pętli) generuje losową temperaturę i jeśli przekroczy ona 40 stopni, wywołuje zdarzenie "OnOverheat". Równolegle stwórz klasę "Rejestrator", która posiada prywatną listę stringów o nazwie "Logi". Zadaniem Rejestratora jest subskrybowanie zdarzenia z Termometru i za każdym razem, gdy nastąpi przegrzanie, dopisanie do swojej listy notatki: "ALARM: Temperatura wyniosła X stopni o godzinie Y". W Main uruchom symulację pracy serwerowni przez 10 cykli, a na koniec poproś klasę Rejestrator o wyświetlenie wszystkich zebranych logów. To zadanie uczy, jak obiekty mogą ze sobą współpracować bez bezpośredniego wywoływania swoich metod – Termometr tylko "krzyczy", że jest gorąco, a Rejestrator "słucha" i notuje. Jest to modelowy przykład separacji obowiązków (Separation of Concerns). Upewnij się, że Rejestrator poprawnie odpina się od Termometru na koniec programu, co jest dobrą praktyką zarządzania pamięcią w .NET. Finalny raport powinien zawierać chronologiczne zestawienie wszystkich zarejestrowanych incydentów temperatury.
Opanowanie techniki rozszerzania wbudowanych typów języka C# o niestandardową logikę biznesową. Student uczy się tworzyć biblioteki pomocnicze, które są zintegrowane bezpośrednio z obiektami, na których operują.
Pracujesz nad systemem do analizy treści artykułów prasowych. Zamiast tworzyć skomplikowane klasy narzędziowe, musisz napisać trzy metody rozszerzające dla typu string, które będą dostępne dla każdego tekstu w Twojej aplikacji. Pierwsza metoda "LiczSlowa()" powinna zwracać liczbę słów w tekście. Druga metoda "CzyZdanie()" powinna sprawdzać, czy tekst kończy się kropką, pytajnikiem lub wykrzyknikiem. Trzecia metoda "Skroc(int max)" powinna skracać zbyt długi tekst i dodawać na końcu wielokropek. Twoim zadaniem jest zademonstrowanie użycia tych metod w konsoli na kilku przykładowych zdaniach, wywołując je "po kropce" prosto z obiektów typu string (np. "Cześć świat".LiczSlowa()). To zadanie uczy, jak pisać niezwykle czytelny kod, który niemal przypomina naturalny język angielski. Dzięki metodom rozszerzającym Twoja biblioteka do obróbki tekstu staje się niezwykle intuicyjna dla innych deweloperów. Pamiętaj, że wszystkie metody rozszerzające muszą znajdować się w statycznej klasie i posiadać słowo kluczowe "this". Zakończ zadanie wyświetleniem pełnej analizy statystycznej dla dłuższego akapitu tekstu wprowadzonego przez użytkownika.