Head First C#. Edycja polska - ebook
Head First C#. Edycja polska - ebook
Język programowania C# został zaprojektowany specjalnie dla firmy Microsoft. C# czerpie najlepsze wzorce z języka Java oraz C++. Aktualnie dostępna wersja 3.0 zawiera takie elementy jak automatyczne oczyszczanie pamięci, typy ogólne, dynamiczne tworzenie kodu i wiele innych. Język C# zawiera bogatą bibliotekę klas pozwalających na tworzenie i rozwijanie aplikacji okienkowych, bazodanowych, a także dynamicznych aplikacji internetowych. Rozwiązanie to zdobyło już swoją pozycję na rynku języków programowania, a narzędzia dla programistów dostarczane przez firmę Microsoft sprawiają, że pozycja ta wydaje się niezagrożona.
W książce "Head First C#. Edycja polska" autorzy, jak zwykle w charakterystyczny dla tej serii -- niekonwencjonalny, a przy tym niezwykle skuteczny sposób, nauczą Cię niezbędnych podstaw C#. Lektura tej książki pozwoli Ci na swobodne poruszanie się wśród takich zagadnień jak wykorzystanie interfejsów czy też dziedziczenie. Dowiesz się, w jaki sposób obsługiwać wyjątki oraz zapisywać dane do pliku, aby potem je z niego odczytać. Nauczysz się korzystać z języka LINQ, a także odbędziesz krótki kurs korzystania z Visual Studio. Sposób, w jaki została napisana ta książka, gwarantuje, że szybko i z łatwością opanujesz język C#!
- Podstawy C#
- Typy danych wykorzystywane w C#
- Wykorzystanie interfejsów oraz klas abstrakcyjnych
- Zastosowanie typów wyliczeniowych i kolekcji
- Sposób wykorzystania plików do przechowywania danych
- Wykorzystanie zdarzeń i delegacji
- Zastosowania języka LINQ
- Visual Studio -- sposób na wydajniejsze tworzenie aplikacji
Poznaj język C# szybko, łatwo i przyjemnie!
Spis treści
Wstęp
- Dla kogo jest ta książka? (30)
- Wiemy, o czym myślisz (31)
- Metapoznanie: myślenie o myśleniu (33)
- Oto, co możesz zrobić, aby wysłać mózg na misję (35)
- Przeczytaj to (37)
- Grupa korektorów technicznych (38)
- Podziękowania (39)
Rozdział 1. Aplikacje Visual Studio w 10 minut lub mniej
- Dlaczego powinieneś uczyć się C# (42)
- C# oraz Visual Studio ułatwiają wiele czynności (43)
- Pomóż dyrektorowi naczelnemu zrezygnować z papieru (44)
- Sprawdź potrzeby Twoich użytkowników, zanim zaczniesz tworzyć program (45)
- Oto program, który zamierzasz stworzyć (46)
- Co robisz w Visual Studio (48)
- Co Visual Studio robi za Ciebie (48)
- Stwórz interfejs użytkownika (52)
- Visual Studio za kulisami (54)
- Dodaj coś do kodu generowanego automatycznie (55)
- Możesz już uruchomić aplikację (56)
- Potrzebujemy bazy danych do przechowywania naszych informacji (58)
- Tworzenie tabeli dla listy kontaktowej (60)
- Pola na karcie kontaktowej stają się kolumnami w tabeli People (62)
- Zakończ tworzenie tabeli (65)
- Utwórz diagram dla swoich danych, aby aplikacja miała do nich dostęp (66)
- Wstaw dane z kart do bazy (68)
- Połącz formularz z bazą danych, korzystając ze źródeł danych (70)
- Dodaj kontrolki powiązane z bazą danych do formularza (72)
- Dobre programy są intuicyjne w użyciu (74)
- Jak zamienić TWOJĄ aplikację w aplikację WSZYSTKICH (77)
- Daj innym użytkownikom możliwość korzystania z Twojej aplikacji (78)
- Jeszcze nie skończyłeś: przetestuj instalację (79)
- Stworzyłeś pełnowartościową aplikację bazodanową (80)
Rozdział 2. Pod maską
- Kiedy robisz to... (82)
- ...IDE robi to (83)
- Skąd się biorą programy (84)
- IDE pomaga Ci kodować (86)
- Kiedy zmieniasz coś w IDE, zmieniasz także swój kod (88)
- Anatomia programu (90)
- Twój program wie, skąd zacząć (92)
- Możesz zmienić punkt wejścia programu (94)
- W tej samej przestrzeni nazw mogą być dwie klasy (99)
- Twoje programy używają zmiennych do pracy z danymi (100)
- C# używa znanych symboli matematycznych (102)
- Pętle wykonują czynność wielokrotnie (103)
- Kodowanie czas zacząć (104)
- Instrukcje if/else podejmują decyzje (105)
- Ustal warunki i sprawdź, czy są prawdziwe (106)
Rozdział 3. Tworzenie kodu ma sens
- W jaki sposób Mike myśli o swoich problemach (122)
- W jaki sposób system nawigacyjny w samochodzie Mike'a rozwiązuje jego problemy (123)
- Klasa Navigator napisana przez Mike'a posiada metody do ustalania i modyfikacji tras (124)
- Wykorzystaj to, czego się nauczyłeś, do napisania prostej aplikacji (125)
- Mike ma pewien pomysł (126)
- Mike może użyć obiektów do rozwiązania swojego problemu (127)
- Używasz klasy do utworzenia obiektu (128)
- Kiedy tworzysz obiekt na podstawie klasy, to taki obiekt nazywamy instancją klasy (129)
- Lepsze rozwiązanie... uzyskane dzięki obiektom! (130)
- Instancja używa pól do przechowywania danych na temat różnych rzeczy (134)
- Stwórzmy kilka instancji! (135)
- Dzięki za pamięć (136)
- Co Twój program ma na myśli (137)
- Możesz używać nazw klas i metod w celu uczynienia kodu bardziej intuicyjnym (138)
- Nadaj swojej klasie naturalną strukturę (140)
- Diagramy klas pozwalają w sensowny sposób zorganizować klasy (142)
- Utwórz klasę do pracy z kilkoma facetami (146)
- Stwórz projekt dla facetów (147)
- Stwórz formularz do interakcji z facetami (148)
- Jest jeszcze prostszy sposób inicjalizacji obiektów (151)
- Kilka pomysłów na projektowanie intuicyjnych klas (152)
Rozdział 4. Jest 10:00. Czy wiesz, gdzie są Twoje dane?
- Typ zmiennej określa rodzaj danych, jakie zmienna może przechowywać (158)
- Zmienna jest jak kubek z danymi (160)
- 10 kilogramów danych w pięciokilogramowej torebce (161)
- Nawet wtedy, gdy liczba ma prawidłowy rozmiar, nie możesz przypisać jej do każdej zmiennej (162)
- Kiedy rzutujesz wartość, która jest zbyt duża, C# dopasuje ją automatycznie (163)
- C# przeprowadza niektóre rzutowania automatycznie (164)
- Kiedy wywołujesz metodę, zmienne muszą pasować do typów parametrów (165)
- Połączenie = z operatorem (170)
- Obiekty także są zmiennymi (171)
- Korzystaj ze swoich obiektów przy pomocy zmiennych referencyjnych (172)
- Referencje są jak etykiety do Twoich obiektów (173)
- Jeżeli nie ma już żadnej referencji, Twoje obiekty są usuwane z pamięci (174)
- Referencje wielokrotne i ich efekty uboczne (175)
- Dwie referencje oznaczają DWA sposoby na zmianę danych obiektu (180)
- Specjalny przypadek: tablice (181)
- Tablice mogą także zawierać grupę zmiennych referencyjnych (182)
- Witamy w barze Niechlujny Janek - najtańsze kanapki w mieście! (183)
- Obiekty używają referencji do komunikacji między sobą (185)
- Tam gdzie obiektów jeszcze nie było (186)
Laboratorium C# numer 1. Dzień na wyścigach
- Specyfikacja: stwórz symulator wyścigów (196)
- Końcowy produkt (204)
Rozdział 5. Co ma być ukryte... niech będzie ukryte
- Krystyna planuje przyjęcia (206)
- Co powinien robić program szacujący? (207)
- Jazda próbna Krystyny (212)
- Każda opcja powinna być obliczana indywidualnie (214)
- Bardzo łatwo przez przypadek źle skorzystać z obiektów (216)
- Hermetyzacja oznacza, że niektóre dane w klasie są prywatne (217)
- Użyj hermetyzacji w celu kontroli dostępu do metod i pól Twojej klasy (218)
- Ale czy jego prawdziwa tożsamość jest NAPRAWDĘ chroniona? (219)
- Dostęp do prywatnych pól i metod można uzyskać tylko z wnętrza klasy (220)
- Kilka sugestii dotyczących hermetyzacji (223)
- Hermetyzacja utrzymuje Twoje dane w nieskazitelnym stanie (224)
- Właściwości sprawią, że hermetyzacja będzie łatwiejsza (225)
- Stwórz aplikację do przetestowania klasy Farmer (226)
- Użyj automatycznych właściwości do ukończenia klasy (227)
- Co wtedy, gdy chcemy zmienić pole mnożnika wyżywienia? (228)
- Użyj konstruktora do inicjalizacji pól prywatnych (229)
Rozdział 6. Drzewo genealogiczne Twoich obiektów
- Krystyna organizuje także przyjęcia urodzinowe (238)
- Potrzebujemy klasy BirthdayParty (239)
- Jeszcze jedna rzecz... Czy możesz dodać opłatę 100 zł za przyjęcia powyżej 12 osób? (245)
- Kiedy klasy używają dziedziczenia, kod musi być napisany tylko raz (246)
- Zbuduj model klasy, rozpoczynając od rzeczy ogólnych i przechodząc do bardziej konkretnych (247)
- W jaki sposób zaprojektowałbyś symulator zoo? (248)
- Użyj dziedziczenia w celu uniknięcia zwielokrotniania kodu w klasach potomnych (249)
- Różne zwierzęta wydają różne dźwięki (250)
- Pomyśl, w jaki sposób pogrupować zwierzęta (251)
- Stwórz hierarchię klas (252)
- Każda klasa pochodna rozszerza klasę bazową (253)
- Aby dziedziczyć z klasy bazowej, użyj dwukropka (254)
- Wiemy, że dziedziczenie dodaje pola, właściwości i metody klasy bazowej... (257)
- Klasa pochodna może przesłaniać odziedziczone metody w celu ich modyfikacji lub zmiany (258)
- W każdym miejscu, gdzie możesz użyć klasy bazowej, możesz zamiast tego użyć jednej z jej klas pochodnych (259)
- Klasa potomna może uzyskać dostęp do klasy bazowej, używając słowa kluczowego base (264)
- Jeśli Twoja klasa bazowa posiada konstruktor, klasa pochodna też musi go mieć (265)
- Teraz jesteś już gotowy do dokończenia zadania Krystyny (266)
- Stwórz system zarządzania ulem (271)
- Najpierw stworzysz system podstawowy (272)
- Użyj dziedziczenia, aby rozszerzyć system zarządzania pszczołami (278)
Rozdział 7. Klasy, które dotrzymują swoich obietnic
- Wróćmy do pszczelej korporacji (282)
- Możemy użyć dziedziczenia do utworzenia klas dla różnych typów pszczół (283)
- Interfejs daje klasie do zrozumienia, że musi zaimplementować określone metody i właściwości (284)
- Użyj słowa kluczowego interface do zdefiniowania interfejsu (285)
- Teraz możesz utworzyć instancję NectarStinger, która będzie wykonywała dwa rodzaje zadań (286)
- Klasy implementujące interfejsy muszą zawierać WSZYSTKIE ich metody (287)
- Poćwicz trochę z interfejsami (288)
- Nie możesz stworzyć instancji interfejsu, ale możesz uzyskać jego referencję (290)
- Referencje interfejsów działają tak samo jak referencje obiektów (291)
- Za pomocą "is" możesz sprawdzić, czy klasa implementuje określony interfejs (292)
- Interfejsy mogą dziedziczyć z innych interfejsów (293)
- RoboBee 4000 może wykonywać zadania pszczół bez potrzeby spożywania cennego miodu (294)
- is określa, co obiekt implementuje, as mówi kompilatorowi, jak go traktować (295)
- Ekspres do kawy także jest urządzeniem (296)
- Rzutowanie w górę działa w odniesieniu do obiektów i interfejsów (297)
- Rzutowanie w dół pozwala zamienić urządzenie z powrotem w ekspres do kawy (298)
- Rzutowanie w górę i w dół działa także w odniesieniu do interfejsów (299)
- Jest coś więcej niż tylko public i private (303)
- Modyfikatory dostępu zmieniają zasięg (304)
- Obiekty niektórych klas nigdy nie powinny być tworzone (307)
- Klasa abstrakcyjna jest jak skrzyżowanie klasy i interfejsu (308)
- Obiekty niektórych klas nigdy nie powinny być tworzone (310)
- Metoda abstrakcyjna nie ma ciała (311)
- Polimorfizm oznacza, że jeden obiekt może przyjmować wiele różnych postaci (319)
Rozdział 8. Przechowywanie dużej ilości danych
- Łańcuchy znaków nie zawsze sprawdzają się przy przechowywaniu kategorii danych (338)
- Typy wyliczeniowe pozwalają Ci wyliczyć prawidłowe wartości (339)
- Typy wyliczeniowe pozwalają na reprezentowanie liczb za pomocą nazw (340)
- Możesz użyć tablicy, aby stworzyć talię kart... (343)
- Z tablicami ciężko się pracuje (344)
- Listy ułatwiają przechowywanie kolekcji... czegokolwiek (345)
- Listy są bardziej elastyczne niż tablice (346)
- Listy kurczą się i rosną dynamicznie (349)
- Obiekty List mogą przechowywać każdy typ (350)
- Inicjalizatory kolekcji działają tak samo jak inicjalizatory obiektu (354)
- Stwórzmy listę kaczek (355)
- Listy są proste, ale SORTOWANIE może być skomplikowane (356)
- Dwa sposoby na posortowanie kaczek (357)
- Użyj interfejsu IComparer, aby powiedzieć liście, jak ma sortować (358)
- Stwórz instancję obiektu porównującego (359)
- IComparer może wykonywać złożone porównania (360)
- Użyj słownika do przechowywania kluczy i wartości (363)
- Ograniczenia funkcjonalności słownika (364)
- Twoje klucze i wartości mogą być także różnego typu (365)
- Możesz tworzyć własne przeciążone metody (371)
- I jeszcze WIĘCEJ typów kolekcji... (383)
- Kolejka działa według reguły: pierwszy przyszedł, pierwszy wyszedł (384)
- Stos działa według reguły: ostatni przyszedł, pierwszy wyszedł (385)
Laboratorium C# numer 2. Wyprawa
- Specyfikacja: stwórz grę przygodową (390)
- Zabawa dopiero się zaczyna! (410)
Rozdział 9. Zapisz tablice bajtów, zapisz świat
- C# używa strumieni do zapisu i odczytu danych (412)
- Różne strumienie zapisują i odczytują różne rzeczy (413)
- FileStream zapisuje bajty do pliku (414)
- Zapis i odczyt wymaga dwóch obiektów (419)
- Dane mogą przechodzić przez więcej niż jeden strumień (420)
- Użyj wbudowanych obiektów do wyświetlenia standardowych kien dialogowych (423)
- Okna dialogowe także są obiektami (425)
- Używaj wbudowanych klas File oraz Directory do pracy z plikami i katalogami (426)
- Używaj okien dialogowych do otwierania i zapisywania plików (429)
- Dzięki IDisposable obiekty usuwane są prawidłowo (431)
- Unikaj błędów systemowych, korzystając z instrukcji using (432)
- Zapisywanie danych do plików wymaga wielu decyzji (438)
- Użyj instrukcji switch do wyboru właściwej opcji (439)
- Dodaj przeciążony konstruktor Deck(), który wczytuje karty z pliku (441)
- Co dzieje się z obiektem podczas serializacji? (443)
- Czym w istocie JEST stan obiektu? Co musi zostać w nim zapisane? (444)
- Kiedy obiekt jest serializowany, serializowane są także wszystkie obiekty z nim powiązane... (445)
- Serializacja pozwala Ci zapisywać lub odczytywać całe obiekty na raz (446)
- Jeżeli chcesz stosować serializację w odniesieniu do klasy, to musisz oznaczyć ją atrybutem [Serializable\ (447)
- .NET automatycznie konwertuje tekst do postaci Unicode (451)
- C# może użyć tablicy bajtów do przesyłania danych (452)
- Do zapisywania danych binarnych używaj klasy BinaryWriter (453)
- Pliki utworzone dzięki serializacji mogą być czytane także ręcznie (455)
- StreamReader i StreamWriter będą do tego odpowiednie (459)
Rozdział 10. Gaszenie pożarów nie jest już popularne
- Damian potrzebuje swoich wymówek, aby być mobilnym (464)
- Kiedy program wyrzuca wyjątek, .NET tworzy obiekt Exception (468)
- Kod Damiana zrobił coś nieoczekiwanego (470)
- Wszystkie obiekty wyjątków dziedziczą z Exception (472)
- Debuger pozwala Ci wyśledzić wyjątki w kodzie i zapobiec im (473)
- Użyj debugera wbudowanego w IDE, aby znaleźć problem w programie do zarządzania wymówkami (474)
- Oj, oj! - w kodzie dalej są błędy... (477)
- Obsłuż wyjątki za pomocą try i catch (479)
- Co się stanie, jeżeli wywoływana metoda jest niebezpieczna? (480)
- Użyj debugera do prześledzenia przepływu try/catch (482)
- Jeśli posiadasz kod, który powinien być uruchomiony ZAWSZE, zastosuj finally (484)
- Użyj obiektu Exception w celu uzyskania informacji o problemie (489)
- Użyj więcej niż jednego bloku catch do wyłapania różnych typów wyjątków (490)
- Jedna klasa wyrzuca wyjątek, inna klasa go wyłapuje (491)
- Pszczoły i ich wyjątek OutOfHoney (492)
- Łatwy sposób na uniknięcie licznych problemów: using umożliwia Ci stosowanie try i finally za darmo (495)
- Unikanie wyjątków: zaimplementuj IDisposable, aby przeprowadzić własne procedury sprzątania (496)
- Najgorszy z możliwych blok catch: komentarze (498)
- Tymczasowe rozwiązania są dobre (tymczasowo) (499)
- Kilka wskazówek dotyczących obsługi wyjątków (500)
- Damian w końcu pojechał na urlop... (503)
Rozdział 11. Co robi Twój kod, kiedy nie patrzysz
- Czy kiedykolwiek marzyłeś o tym, aby Twoje obiekty potrafiły samodzielnie myśleć? (506)
- Ale skąd obiekt WIE, że ma odpowiedzieć? (506)
- Kiedy wystąpi ZDARZENIE... obiekty nasłuchują (507)
- Jeden obiekt wywołuje zdarzenie, inne nasłuchują... (508)
- Potem inne obiekty obsługują zdarzenie (509)
- Łącząc punkty (510)
- IDE automatycznie tworzy za Ciebie funkcje obsługi zdarzeń (514)
- Wszystkie formularze, które utworzyłeś, używają zdarzeń (520)
- Połączenie nadawców zdarzenia z jego odbiorcami (522)
- Delegat ZASTĘPUJE właściwą metodę (523)
- Delegat w akcji (524)
- Każdy obiekt może subskrybować publiczne zdarzenie... (527)
- Użyj zamiast zdarzenia funkcji zwrotnej, aby podpiąć dokładnie jeden obiekt do delegatu (529)
- Funkcje zwrotne używają delegatu, NIE zdarzeń (530)
Rozdział 12. Wiedza, moc i tworzenie ciekawych rzeczy
- Przebyłeś długą drogę (538)
- Zajmowaliśmy się także pszczołami (539)
- Architektura symulatora ula (540)
- Budowanie symulatora ula (541)
- Życie i śmierć kwiatów (545)
- Potrzebujemy teraz klasy Bee (546)
- Wypełnianie klasy Hive (554)
- Metoda Go() klasy Hive (555)
- Jesteśmy gotowi na stworzenie świata (556)
- Tworzymy system turowy (557)
- Uczenie pszczół zachowań (564)
- Główny formularz wywołuje Go() dla całego świata (566)
- Możemy użyć obiektu World do pobrania statystyk (567)
- Zegary sygnalizują zdarzenia wielokrotnie (568)
- Zegar w tle używa delegata (569)
- Pracujmy z grupami pszczół (576)
- Kolekcje kolekcjonują... DANE (577)
- LINQ ułatwia pracę z danymi w kolekcjach i bazach danych (579)
Rozdział 13. Upiększ to
- Cały czas do interakcji z programami używałeś kontrolek (586)
- Kontrolki formularza są tylko obiektami (587)
- Dodaj do projektu rendering (590)
- Kontrolki są dobrze przystosowane do wyświetlania różnych elementów wizualnych (592)
- Stwórz swoją pierwszą animowaną kontrolkę (595)
- Twoje kontrolki także muszą usuwać swoje kontrolki! (599)
- UserControl to dobry sposób na tworzenie kontrolek (600)
- Dodaj do projektu formularze reprezentujące ul i pole (604)
- Stwórz klasę Renderer (605)
- Przyjrzyjmy się bliżej sprawom wydajności (612)
- Zmieniłeś rozmiar bitmap przy pomocy obiektu Graphics (614)
- Zasoby Twoich obrazków przechowywane są w postaci obiektów Bitmap (615)
- Użyj System.Drawing do PRZEJĘCIA KONTROLI nad grafiką (616)
- 30-sekundowa podróż do świata tajemnic grafiki GDI+ (617)
- Użyj Graphics, aby na formularzu narysować obrazek (618)
- Klasa Graphics może usunąć problem przezroczystości... (623)
- Użyj zdarzenia Paint, aby grafika była mocno związana z formularzem (624)
- Bliższe spojrzenie na sposób rysowania formularzy i kontrolek (627)
- Podwójne buforowanie czyni animację bardziej płynną (630)
- Podwójne buforowanie jest wbudowane w formularze i kontrolki (631)
- Użyj obiektu Graphics i procedury obsługi zdarzenia do drukowania (636)
- PrintDocument pracuje z obiektem okna dialogowego drukowania i obiektem okna podglądu wydruku (637)
Rozdział 14. Kapitan Wspaniały. Śmierć obiektu
- Kapitan Wspaniały, najbardziej zdumiewający obiekt Objectville, próbuje pokonać arcyźródło zła... (644)
- Twoją ostatnią szansą na ZROBIENIE czegoś... jest użycie finalizatora (650)
- Kiedy DOKŁADNIE wywoływany jest finalizator? (651)
- Dispose() działa z using, a finalizatory działają z mechanizmem odzyskiwania elementów bezużytecznych (652)
- Finalizatory nie mogą polegać na stabilności (654)
- Spraw, aby obiekt serializował się w Dispose() (655)
- W międzyczasie na ulicach Objectville... (658)
- Struktura jest podobna do obiektu... (659)
- ... ale nie znajduje się na stercie (659)
- Wartości są kopiowane, referencje są przypisywane (660)
- Struktury traktowane są jak typy wartościowe, obiekty jak typy referencyjne (661)
- Stos i sterta: więcej na temat pamięci (663)
- Kapitan Wspaniały... nie tak bardzo (667)
- Metody rozszerzające zwiększają funkcjonalność ISTNIEJĄCYCH klas (668)
- Rozszerzanie podstawowego typu: string (670)
Rozdział 15. Przejmij kontrolę nad danymi
- Łatwy projekt... (676)
- ...ale dane są w różnych miejscach (677)
- Dzięki LINQ możesz pobrać dane z różnych źródeł (678)
- Kolekcje .NET są przystosowane do działania z LINQ (679)
- LINQ ułatwia wykonywanie zapytań (680)
- LINQ jest prosty, ale Twoje zapytania wcale takie być nie muszą (681)
- LINQ ma wiele zastosowań (684)
- LINQ może połączyć Twoje wyniki w grupy (689)
- Połącz wartości Janka w grupy (690)
- Użyj Join do połączenia dwóch kolekcji w jednym zapytaniu (693)
- Janek zaoszczędził kupę szmalu (694)
- Połącz LINQ z bazą danych SQL (696)
- Użyj join, aby połączyć Starbuzz i Objectville (700)
Laboratorium C# numer 3. Invaders
- Dziadek wszystkich gier (704)
- Można zrobić znacznie więcej... (723)
Dodatek A 5 najważniejszych rzeczy, które chcieliśmy umieścić w tej książce
- 1. Zastosowanie LINQ do XML (726)
- 2. Refaktoryzacja (728)
- 3. Niektóre z naszych ulubionych komponentów okna Toolbox (730)
- 4. Aplikacje konsolowe (732)
- 5. Windows Presentation Foundation (734)
- Czy wiesz, że C# i .NET Framework potrafią... (736)
Skorowidz (739)
Kategoria: | Programowanie |
Zabezpieczenie: |
Watermark
|
ISBN: | 978-83-246-5933-3 |
Rozmiar pliku: | 21 MB |