Laboratorium 1.1
Wprowadzenie do C# VS 2022 .net core 8.0
- Wstęp
W 2000 r. Microsoft przedstawił pomysł standaryzacji oprogramowania na platformę Windows. Główne cechy .net:- nowe biblioteki
- nowe narzędzia
- niezależność językowa (VB,C#,C++,J#, i dziesiątki innych)
- niezależność platformowa dzięki CIL - Common Intermediate Language
- implementacje na Linuxa np. mono czy dotGNU
- w pełni obiektowy
- "odśmiecaniem" pamięci zajmuje się środowisko uruchomieniowe
- zaawansowane mechanizmy programistyczne (delegaty, refleksje, typy generyczne, lambdy, zapytania LINQ itp.)
- pojedynczy pakiet np. mscorelib.dll może zawierać wiele przestrzeni nazw
- każda przestrzeń nazw może zawierać wiele typów
Kilka wybranych przestrzeni nazw:- System - wiele przydatnych typów związanych z danymi wewnętrznymi, zmiennymi środowiskowymi i odśmiecaniem, jak również wiele powszechnie stosowanych wyjątków i atrybutów.
- System.Collections - Definicja wielu typów kontenerowych, jak również bazowe typy i interfejsy, pozwalające budować niestandardowe kolekcje.
- System.Data, System.data - Komunikacja z relacyjnymi bazami danych za pomocą ADO.NET
- System.IO - Wiele typów używanych w plikowych operacjach we/wy, kompresji danych i manipulowaniu portami.
- System.Reflection - Typy obsługujące wykrywanie typów w czasie wykonywania programu, jak również dynamiczne tworzenie typów.
- System.Drawing, System.Windows.Forms - Typy używane do budowania aplikacji okienkowych za pomocą oryginalnego zestawu narzędzi interfejsu użytkownika .Net (Windows Forms)
- System.ServiceModel - Służy do budowania aplikacji rozproszonych z apomocą API WCF (Windows Communication Foundation)
- System.Web - Służy do budowania aplikacji internetowych ASP.NET
- System.Threading - Liczne typy do budowania aplikacji wielowątkowych
- System.Xml - Przestrzenie nazw związane z językiem XML
- Pierwsze kroki w VS (0,5 pkt.)
- Uruchamiamy VS
- Tworzymy nowy projekt

- Wybieramy aplikację konsolową .net core

- Ustawiamy nazwę projektu na HelloWorld i nazwę solucji na Lab1 resztę można zostawić domyślnie

- Upewniamy się czy mamy ustawioną wersję .net core 8.0 (lub nowszą)
- W przypadku VS2022 i .net 6+ należy zwrócić uwagę by zaznaczyć pole "Do not use top-level statement".

Gdy nie widzimy dyrektyw using można je włączyć wyłączając globalne dyrektywy, wtedy trzeba zwrócić uwagę, że musimy ręcznie dodać linię using System; na początku pliku cs.- W tym celu zaznaczamy projekt
- Otworzy nam się plik konfiguracyjny
- Zmieniamy wartość w tagu
<ImplicitUsings>enable</ImplicitUsings>na<ImplicitUsings>disable</ImplicitUsings> - Zapisujemy (ctrl+s)
- Można też wejść we właściwości projektu

- Gdy wrócimy do program.cs to zobaczymy, że słowo Console jest podkreślone. Powodem jest brak dyrektywy using w nagłówku programu

- Jak widać aplikacja napisała się sama :)
- Uruchamiamy poprzez F5
- Omówienie kodu i różne próby uruchomienia. (0,5 pkt.)
-
using System; namespace HelloWorld { class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); } } } - Na samej górze kodu źródłowego mamy zdefiniowane używane przestrzenie nazw. W tym przypadku System. To tam znajdziemy Statyczną klasę Console. Bez tego każde użycie Console wymagałoby od nas podawania przedrostka System. (Np.
System.Console.Write("a b c");). To jest jak import w java lub jak include w c/c++.- Usuń linię z using i spróbuj skompilować (F5).
- Dodaj przedrostek System. do klasy wywołania Console.
Można to zrobić zapisać ręcznie lub posłużyć się podpowiadaczem (rozwinąć symbol żarówki): - Podpowiadacz wskazuje 4 rozwiązania. Wybierzmy to drugie - przedrostek System.
- Jak widać błąd zniknął ale kolejne odwołanie się do klas w przestrzeni nazw System będzie wymagało od nas podawania przedrostka System. Dlatego wygodniej podać to raz przy pomocy "using".
- Gdy istnieje konflikt nazw (np identyczna nazwa klasy w dwóch różnych przestrzeniach nazw) można użyć pełnego przedrostka, lub aliasu. np. using s = System; a następnie s.Console
- Nasz projekt też ma swoją przestrzeń nazw "HelloWorld". W przypadku pisania projektu biblioteki można odnosić się do klas w niej zawartych przy pomocy przedrostka HelloWorld lub używać using HelloWorld.
- W przestrzeni nazw znajduje się właściwa deklaracja klas i zmiennych.
- Programy konsolowe muszą mieć statyczną metodę Main wywoływaną w momencie startu programu. Metoda ta posiada parametr w postaci tablicy stringów args.
- Linia
Console.WriteLine("text")wypisuje podany napis na ekran. - Odszukaj na dysku katalog gdzie założona została solucja.
- Wejdź w katalog HelloWorld/bin/Debug/net8.0
- Tam znajduje się skompilowany program wraz plikami konfiguracyjnymi
- Uruchom, przez dwuklik program HelloWorld.exe (program uruchomi się i zamknie).
- W pasku systemowym kliknij szukaj i wpisz cmd.

- Uruchom Developer Command Prompt for VS
- Z paska eksploratora plików skopiuj położenie katalogu

- i wykonaj w konsoli polecenie cd <ścieżka do katalogu>

- Uruchom HelloWorld.exe
- Teraz jak widać faktycznie wyświetlił się napis.
-
- Przekazanie parametrów i proste konstrukcje. (0,5 pkt.)
- Ustaw kursor pod linią z wypisywniem Hello World i wpisz napis "fore". Zauważ, że VS podpowiada rozwinięcie tego słowa do foreach w dwóch wariantach. Jeden na bazie copilota gdzie użyje najbardziej prawdopodobnej w tym kontekście składni

drugi z intelisence gdzie wstawi szablon składni pętli foreach.
- Użyj klawisza TAB w celu autogenerowania kodu dotyczącego pętli fereach. W przypadku gdyby "podpowiadacz" zniknął można go reaktywować kombinacją "ctrl+Space"

- W tym drugim przypadku można ustawić typ danych w kolekcji, nazwę iteratora oraz wskazać kolekcję. Pomiędzy poszczególnymi polami przechodzimy z pomocą klawisza TAB.
Uzupełnij kod pętli wypisywaniem poszczególnych argumentów
foreach (string arg in args) { Console.WriteLine($"Argument: {arg}"); } - Kliknij prawym klawiszem na projekcie Hello World w panelu Solution Eksplorera i uruchom przebudowanie projektu (rebuild)

- Otwórz ponownie lokalizację HelloWorld.exe z konsoli developera lub komend (cmd) i uruchom program w następujący sposób:
HelloWorld.exe Ala ma kota
Hello World!
Argument: Alice
Argument: has
Argument: a - Argument: cat
- Za pomocą menu kontekstowego otwórz właściwości projektu HelloWorld (lub Alt+Enter) przejdź do zakładki "Debug", kliknij w Open debug launch profiles UI

i w polu Command line arguments wpisz swoje argumenty:
- Uruchom program w trybie debug (F5)
- Zamiast napisu Hello World wyświetl liczbę argumentów podanych przez użytkownika. Można się posłużyć właściwością args.Length lub rozszerzeniem args.Count()
- Dodaj deklarację zmiennej typu int: int counter = 0; Oprócz wartości argumentu wypisz wartość licznika, z jednoczesną post inkrementacją (counter++);
- Zamień post inkrementację na pre inkrementację (++conter) uruchom jeszcze raz i zobacz różnicę.
- Ustaw kursor pod linią z wypisywniem Hello World i wpisz napis "fore". Zauważ, że VS podpowiada rozwinięcie tego słowa do foreach w dwóch wariantach. Jeden na bazie copilota gdzie użyje najbardziej prawdopodobnej w tym kontekście składni
- Debug (0,5 pkt.)
- Ustaw się w linii z wypisywaniem numeru i wartości argumentu i naciśnij F9. Można też kliknąć w obszarze lewego marginesu w celu dodania break pointa.

- Uruchom w trybie debug (F5)
- Program zatrzyma się a my możemy podejrzeć wartości zmiennych wskazując myszą interesujące nas wartości:

- Dalsze krokowe śledzenie programu to F10 lub wejście w metodę (F11). Kontynuacja do kolejnego punktu przerwania F5
- Klikając prawym klawiszem na zmienną counter możemy dodać śledzenie zmiennej w okienku "Watch".


- Klikamy prawym klawiszem na break point i z menu kontekstowego wybieramy "conditions"

- Tam wstawiamy warunek zatrzymania na danym punkcie przerwania counter == 2
- Uruchamiamy program przez F5 i sprawdzamy jaką wartość ma counter przy pierwszym zatrzymaniu.
- Ustaw się w linii z wypisywaniem numeru i wartości argumentu i naciśnij F9. Można też kliknąć w obszarze lewego marginesu w celu dodania break pointa.
- Pobieranie danych (0,5 pkt.)
- W solution explorerze z menu kontekstowego solucji wybierz Add/New Project
- Dodaj aplikację konsolową o nazwie MultiplicationTable
- Z menu kontekstowego nowego projektu ustaw domyślny projekt startowy:

- Zadeklaruj dwie zmienne xMax i yMax typu integer.
- Zadeklaruj dwie zmienne typu string? xStr i yStr. (znak zapytania oznacza zmienną nulowalną, taką dostaniemy z metody ReadLine())
- Przy pomocy Console.WriteLine wypisz linię zachęty do wprowadzenia wartości x (reprezentowaną przez zmienną xMax )
- Przy pomocy Console.ReadLine() odczytaj wprowadzony przez użytkownika string (xStr).
- Przy pomocy statycznej metody int.TryParse spróbuj przekonwertować napis w wartość typu integer. int.TryParse(xStr, out xMax )
- Zwrotnie dostajemy true/false. Sprawdź za pomocą instrukcji warunkowej if czy konwersja się powiodła w przeciwnym wypadku wyświetl komunikat błędu.
- Pobierz od użytkownika yStr i wykonaj analogiczne operacje jak w przypadku xStr (konwersja, sprawdzenie)
- Uruchom program podając błędne dane (np. litery zamiast liczb).
- W drugim przypadku dostaniemy wyjątek

- Umieść część parsującą w bloku try catch
try { yMax = int.Parse(yStr); } catch (FormatException fe) { Console.WriteLine("Oh no! " + fe.Message); } finally { Console.WriteLine("something else"); } - Część catch jest wykonywana gdy złapiemy wyjątek określonego typu
- Dorobić do powyższego projektu następującą funkcjonalność:
- użytkownik podaje maksymalne rozmiary tabliczki mnożenia
- Wyświetlana jest tabliczka o podanych rozmiarach
- Do wykonania tego zadania należy posłużyć się
- podwójną pętlą for,
- formatowanym (do 2 cyfr) wyświetlaniem liczb {liczba:d2},
- wypisywaniem bez łamania linii Console.Write
- Efekt powinien wyglądać mniej więcej tak:

- Nowa klasa (0,5pkt.)
- Z menu kontekstowego projektu (w solution explorerze) wybieramy Add/New Item i tam wskazujemy Class (można też na skróty Add/New Class). Klasa powinna być dodana do projektu nie do solucji.
- Podajemy nazwę FormatField

- Zaimplementuj metodę Field w następujący sposób:
namespace MultiplicationTable { public static class FormatField { public static string Field(int number, int width) { return number.ToString().PadLeft(width) + "|"; } } } - Użyć FormatField.Field do formatowania.
- Nowa biblioteka (0,5 pkt.)
- Do solucji dodajemy nowy projekt typu class library

- Nazwijmy go TableCreatorLib
- Zaznaczamy kod Class1.cs i zmieniamy jego nazwę (F2) na TableCreator

- Visual Studio zaproponuje także zmianę nazwy klasy. Zgadzamy się.
- Realizujemy klasę zgodnie z poniższym:
using System; using System.Linq; namespace TableCreatorLib { public class TableCreator { private int[,] table; private int x, y; public int Count { get; private set; } public TableCreator(int x, int y) { Count = 0; this.x = x; this.y = y; table = new int[x,y]; } public bool AddItem(int item) { if (Count >= x * y) return false; table[Count % x ,Count / x] = item; Count++; return true; } public void PrintTable() { int maxValue = table.Cast<int>().Max(); int maxLength = maxValue.ToString().Length; for (int i = 0; i < y; i++) { for (int j = 0; j < x; j++) { Console.Write(table[j, i].ToString().PadLeft(maxLength) + "|"); } Console.WriteLine(); } } } } - W projekcie MultiplicationTable dodajemy referencję do nowej biblioteki


- Użyjemy biblioteki TableCreatorLib w celu zebrania i wyświetlenie tabelki.
- Modyfikujemy kod wyświetlający tabelkę tak by jednocześnie dodawać policzone elementy do TableCreatora (tc).
- TableCreator zlicza jaką ma maksymalną wartość i w zależności od tego dopasowuje formatowanie. Przykłady wywołań:

- Do solucji dodajemy nowy projekt typu class library
- Samodzielne zadanie (1,5 pkt.)
- Utworzyć nową solucję w której zawrzecie projekt typu consola .net core oraz projekt typu biblioteka.
- W bibliotece ma być klasa tworząca ciąg Fibonacciego (kolejny element ciągu to suma dwóch poprzednich)
- Klasa powinna posiadać konstruktor z parametrem do którego elementu ciąg ma być liczony.
- W klasie powinny znaleźć się dwie metody, Print i Get. Print wyświetli ciąg na ekran. Get zwróci ciąg w postaci listy int.
- W projekcie konsolowym Zademonstrować działanie biblioteki. Czyli pobrać od użytkownika pewną wartość, utworzyć obiekt naszej klasy i wywołać odpowiednie metody.
