C# od podszewki. Wydanie IV - ebook
C# od podszewki. Wydanie IV - ebook
C# liczy sobie około dwudziestu lat. Jest niestrudzenie rozwijany i doskonalony przez Microsoft, a dzięki swojej wszechstronności znajduje zastosowanie w wielu dziedzinach: pisaniu gier komputerowych, tworzeniu skalowalnych i niezawodnych aplikacji internetowych oraz aplikacji mobilnych, a nawet niskopoziomowym programowaniu komponentów większych systemów. Twórcy C# postawili na obiektowość, ścisłą kontrolę typów, a przede wszystkim na prostotę w stosowaniu. W tym celu wykorzystano wyniki badań akademickich i połączono je z praktycznymi technikami rozwiązywania problemów. W efekcie C# stał się ulubionym językiem profesjonalistów.
To czwarte wydanie podręcznika przeznaczonego dla programistów C#, którzy znają podstawy tego języka, jednak zależy im na dogłębnym zrozumieniu ważnych pojęć i przyswojeniu różnych sposobów myślenia o pozornie znanych zagadnieniach. W książce skrótowo opisano wersje C# od 2 do 5, a wyczerpująco omówiono wersje od 6 do 7.3. Zaprezentowano również niektóre informacje o projektowanych nowych elementach języka C# 8, takich jak typy referencyjne przyjmujące wartość null, wyrażenia switch, usprawnienia dopasowywania wzorców, a także dalsza integracja asynchroniczności z podstawowymi mechanizmami języka. Poszczególne treści zilustrowano licznymi przykładami kodu źródłowego.
W tej książce między innymi:
- wyrażenia lambda, inicjalizatory zapytań, asynchroniczność
- składowe z ciałem w postaci wyrażenia
- zaawansowane techniki pracy z ciągami znaków
- zagadnienia integracji krotek z językiem
- dekonstruktory i dopasowywanie wzorców
- nowe techniki stosowania referencji i powiązanych mechanizmów
C#. Programowanie na najwyższym poziomie!
Spis treści
Przedmowa 17
Wprowadzenie 19
Podziękowania 21
O książce 23
O autorze 27
CZĘŚĆ 1. KONTEKST JĘZYKA C# 29
Rozdział 1. Przetrwają najbystrzejsi 31
- 1.1. Ewoluujący język 31
- 1.1.1. System typów pomocny w dużej i małej skali 32
- 1.1.2. Jeszcze bardziej zwięzły kod 34
- 1.1.3. Prosty dostęp do danych w technologii LINQ 38
- 1.1.4. Asynchroniczność 38
- 1.1.5. Równowaga między wydajnością a złożonością 40
- 1.1.6. Przyspieszona ewolucja - używanie podwersji 41
- 1.2. Ewoluująca platforma 42
- 1.3. Ewoluująca społeczność 43
- 1.4. Ewoluująca książka 44
- 1.4.1. Wyjaśnienia na różnym poziomie 45
- 1.4.2. Przykłady, w których wykorzystano projekt Noda Time 45
- 1.4.3. Terminologia 46
- Podsumowanie 47
CZĘŚĆ 2. C# 2 - 5 49
Rozdział 2. C# 2 51
- 2.1. Typy generyczne 52
- 2.1.1. Wprowadzenie z użyciem przykładu - kolekcje przed wprowadzeniem typów generycznych 52
- 2.1.2. Typy generyczne ratują sytuację 55
- 2.1.3. Jakie elementy mogą być generyczne? 59
- 2.1.4. Wnioskowanie typu argumentów określających typ w metodach 60
- 2.1.5. Ograniczenia typów 62
- 2.1.6. Operatory default i typeof 64
- 2.1.7. Inicjowanie typów generycznych i ich stan 67
- 2.2. Typy bezpośrednie przyjmujące wartość null 69
- 2.2.1. Cel - reprezentowanie braku informacji 69
- 2.2.2. Wsparcie w środowisku CLR i platformie - struktura Nullable
70 - 2.2.3. Obsługa dostępna w języku 74
- 2.3. Uproszczone tworzenie delegatów 80
- 2.3.1. Konwersje grupy metod 81
- 2.3.2. Metody anonimowe 81
- 2.3.3. Zgodność delegatów 83
- 2.4. Iteratory 84
- 2.4.1. Wprowadzenie do iteratorów 85
- 2.4.2. Leniwe wykonywanie 86
- 2.4.3. Przetwarzanie instrukcji yield 87
- 2.4.4. Znaczenie leniwego wykonywania 88
- 2.4.5. Przetwarzanie bloków finally 89
- 2.4.6. Znaczenie obsługi bloku finally 92
- 2.4.7. Zarys implementacji 93
- 2.5. Mniej istotne mechanizmy 98
- 2.5.1. Typy częściowe 98
- 2.5.2. Klasy statyczne 100
- 2.5.3. Inny poziom dostępu do getterów i setterów właściwości 101
- 2.5.4. Aliasy przestrzeni nazw 101
- 2.5.5. Dyrektywy pragma 103
- 2.5.6. Bufory o stałej wielkości 104
- 2.5.7. Atrybut InternalsVisibleTo 105
- Podsumowanie 106
Rozdział 3. C# 3 - technologia LINQ i wszystko, co z nią związane 107
- 3.1. Automatycznie implementowane właściwości 108
- 3.2. Niejawne określanie typów 108
- 3.2.1. Terminologia związana z typami 109
- 3.2.2. Zmienne lokalne z typowaniem niejawnym (var) 110
- 3.2.3. Tablice z niejawnym typowaniem 112
- 3.3. Inicjalizatory obiektów i kolekcji 113
- 3.3.1. Wprowadzenie do inicjalizatorów obiektów i kolekcji 113
- 3.3.2. Inicjalizatory obiektów 115
- 3.3.3. Inicjalizatory kolekcji 116
- 3.3.4. Zalety inicjowania za pomocą jednego wyrażenia 118
- 3.4. Typy anonimowe 118
- 3.4.1. Składnia i podstawy działania 119
- 3.4.2. Typ generowany przez kompilator 121
- 3.4.3. Ograniczenia 122
- 3.5. Wyrażenia lambda 123
- 3.5.1. Składnia wyrażeń lambda 124
- 3.5.2. Przechwytywanie zmiennych 126
- 3.5.3. Drzewa wyrażeń 133
- 3.6. Metody rozszerzające 135
- 3.6.1. Deklarowanie metody rozszerzającej 136
- 3.6.2. Wywoływanie metod rozszerzających 136
- 3.6.3. Łączenie wywołań metod w łańcuch 138
- 3.7. Wyrażenia reprezentujące zapytania 140
- 3.7.1. Wyrażenia reprezentujące zapytania są przekształcane z kodu C# na inny kod C# 140
- 3.7.2. Zmienne zakresu i identyfikatory przezroczyste 141
- 3.7.3. Kiedy stosować poszczególne składnie w LINQ? 142
- 3.8. Efekt końcowy - technologia LINQ 143
- Podsumowanie 144
Rozdział 4. Zwiększanie współdziałania z innymi technologiami 145
- 4.1. Typowanie dynamiczne 146
- 4.1.1. Wprowadzenie do typowania dynamicznego 146
- 4.1.2. Dynamiczne operacje poza mechanizmem refleksji 151
- 4.1.3. Krótkie spojrzenie na zaplecze 156
- 4.1.4. Ograniczenia i niespodzianki związane z typowaniem dynamicznym 160
- 4.1.5. Sugestie dotyczące użytkowania 164
- 4.2. Parametry opcjonalne i argumenty nazwane 166
- 4.2.1. Parametry o wartościach domyślnych i argumenty z nazwami 167
- 4.2.2. Określanie znaczenia wywołań metody 168
- 4.2.3. Wpływ na wersjonowanie 170
- 4.3. Usprawnienia w zakresie współdziałania z technologią COM 172
- 4.3.1. Konsolidacja podzespołów PIA 172
- 4.3.2. Parametry opcjonalne w COM 174
- 4.3.3. Indeksery nazwane 175
- 4.4. Wariancja generyczna 176
- 4.4.1. Proste przykłady zastosowania wariancji 176
- 4.4.2. Składnia wariancji w deklaracjach interfejsów i delegatów 178
- 4.4.3. Ograniczenia dotyczące wariancji 179
- 4.4.4. Wariancja generyczna w praktyce 181
- Podsumowanie 183
Rozdział 5. Pisanie kodu asynchronicznego 185
- 5.1. Wprowadzenie do funkcji asynchronicznych 187
- 5.1.1. Bliskie spotkania asynchronicznego stopnia 187
- 5.1.2. Analiza pierwszego przykładu 189
- 5.2. Myślenie o asynchroniczności 190
- 5.2.1. Podstawy asynchronicznego wykonywania kodu 191
- 5.2.2. Konteksty synchronizacji 192
- 5.2.3. Model działania metod asynchronicznych 193
- 5.3. Deklaracje metod asynchronicznych 195
- 5.3.1. Typy wartości zwracanych przez metody asynchroniczne 196
- 5.3.2. Parametry metod asynchronicznych 197
- 5.4. Wyrażenia await 197
- 5.4.1. Wzorzec awaitable 198
- 5.4.2. Ograniczenia dotyczące wyrażeń await 200
- 5.5. Opakowywanie zwracanych wartości 202
- 5.6. Przepływ sterowania w metodzie asynchronicznej 203
- 5.6.1. Na co kod oczekuje i kiedy? 203
- 5.6.2. Przetwarzanie wyrażeń await 205
- 5.6.3. Używanie składowych zgodnych ze wzorcem awaitable 208
- 5.6.4. Wypakowywanie wyjątków 208
- 5.6.5. Ukończenie pracy metody 211
- 5.7. Asynchroniczne funkcje anonimowe 216
- 5.8. Niestandardowe typy zadań w C# 7 217
- 5.8.1. Typ przydatny w 99,9% przypadków - ValueTask
217 - 5.8.2. 0,1% sytuacji - tworzenie własnych niestandardowych typów zadań 220
- 5.8.1. Typ przydatny w 99,9% przypadków - ValueTask
- 5.9. Asynchroniczne metody main w C# 7.1 222
- 5.10. Wskazówki dotyczące korzystania z asynchroniczności 223
- 5.10.1. Jeśli jest to akceptowalne, używaj ConfigureAwait, aby nie przechwytywać kontekstu 223
- 5.10.2. Włączanie przetwarzania równoległego dzięki uruchomieniu wielu niezależnych zadań 225
- 5.10.3. Unikaj łączenia kodu synchronicznego z asynchronicznym 226
- 5.10.4. Wszędzie, gdzie to możliwe, zezwalaj na anulowanie operacji 226
- 5.10.5. Testowanie kodu asynchronicznego 227
- Podsumowanie 228
Rozdział 6. Implementacja asynchroniczności 229
- 6.1. Struktura wygenerowanego kodu 231
- 6.1.1. Metoda kontrolna - przygotowania i pierwszy krok 233
- 6.1.2. Struktura maszyny stanowej 235
- 6.1.3. Metoda MoveNext() (ogólny opis) 238
- 6.1.4. Metoda SetStateMachine i taniec z opakowywaniem maszyny stanowej 240
- 6.2. Prosta implementacja metody MoveNext() 241
- 6.2.1. Kompletny konkretny przykład 241
- 6.2.2. Ogólna struktura metody MoveNext() 243
- 6.2.3. Zbliżenie na wyrażenia await 245
- 6.3. Jak przepływ sterowania wpływa na metodę MoveNext()? 247
- 6.3.1. Przepływ sterowania między wyrażeniami await jest prosty 247
- 6.3.2. Oczekiwanie w pętli 248
- 6.3.3. Oczekiwanie w bloku try/finally 250
- 6.4. Kontekst wykonania i przekazywanie kontekstu 253
- 6.5. Jeszcze o niestandardowych typach zadań 254
- Podsumowanie 255
Rozdział 7. Dodatkowe mechanizmy z C# 5 257
- 7.1. Przechwytywanie zmiennych w pętlach foreach 257
- 7.2. Atrybuty z informacjami o jednostce wywołującej 259
- 7.2.1. Podstawowe działanie 259
- 7.2.2. Rejestrowanie informacji w dzienniku 261
- 7.2.3. Upraszczanie implementacji interfejsu INotifyPropertyChanged 261
- 7.2.4. Przypadki brzegowe dotyczące atrybutów z informacjami o jednostce wywołującej 263
- 7.2.5. Używanie atrybutów z informacjami o jednostce wywołującej w starszych wersjach platformy .NET 269
- Podsumowanie 270
CZĘŚĆ 3. C# 6 271
Rozdział 8. Odchudzone właściwości i składowe z ciałem w postaci wyrażenia 273
- 8.1. Krótka historia właściwości 274
- 8.2. Usprawnienia automatycznie implementowanych właściwości 276
- 8.2.1. Automatycznie implementowane właściwości przeznaczone tylko do odczytu 276
- 8.2.2. Inicjalizowanie automatycznie implementowanych właściwości 277
- 8.2.3. Automatycznie implementowane właściwości w strukturach 279
- 8.3. Składowe z ciałem w postaci wyrażenia 281
- 8.3.1. Jeszcze prostsze obliczanie właściwości tylko do odczytu 281
- 8.2.2. Metody, indeksery i operatory z ciałem w postaci wyrażenia 284
- 8.3.3. Ograniczenia dotyczące składowych z ciałem w postaci wyrażenia w C# 6 286
- 8.3.4. Wskazówki dotyczące używania składowych z ciałem w postaci wyrażenia 287
- Podsumowanie 290
Rozdział 9. Mechanizmy związane z łańcuchami znaków 291
- 9.1. Przypomnienie technik formatowania łańcuchów znaków w .NET 292
- 9.1.1. Proste formatowanie łańcuchów znaków 292
- 9.1.2. Niestandardowe formatowanie z użyciem łańcuchów znaków formatowania 293
- 9.1.3. Lokalizacja 295
- 9.2. Wprowadzenie do literałów tekstowych z interpolacją 299
- 9.2.1. Prosta interpolacja 299
- 9.2.2. Łańcuchy znaków formatowania w literałach tekstowych z interpolacją 300
- 9.2.3. Dosłowne literały tekstowe z interpolacją 300
- 9.2.4. Obsługa literałów tekstowych z interpolacją przez kompilator (część 1.) 302
- 9.3. Lokalizacja z użyciem typu FormattableString 302
- 9.3.1. Obsługa literałów tekstowych z interpolacją przez kompilator (część 2.) 303
- 9.3.2. Formatowanie obiektu typu FormattableString z użyciem określonych ustawień regionalnych 305
- 9.3.3. Inne zastosowania typu FormattableString 306
- 9.3.4. Używanie typu FormattableString w starszych wersjach platformy .NET 310
- 9.4. Zastosowania, wskazówki i ograniczenia 311
- 9.4.1. Programiści i maszyny, ale raczej nie użytkownicy końcowi 311
- 9.4.2. Sztywne ograniczenia literałów tekstowych z interpolacją 314
- 9.4.3. Kiedy można stosować literały tekstowe z interpolacją, ale nie należy tego robić? 315
- 9.5. Dostęp do identyfikatorów za pomocą operatora nameof 317
- 9.5.1. Pierwsze przykłady stosowania operatora nameof 317
- 9.5.2. Standardowe zastosowania operatora nameof 319
- 9.5.3. Sztuczki i kruczki związane z używaniem operatora nameof 322
- Podsumowanie 325
Rozdział 10. Szwedzki stół z funkcjami do pisania zwięzłego kodu 325
- 10.1. Dyrektywa using static 325
- 10.1.1. Importowanie składowych statycznych 326
- 10.1.2. Metody rozszerzające i dyrektywa using static 329
- 10.2. Usprawnienia inicjalizatorów obiektów i kolekcji 331
- 10.2.1. Indeksery w inicjalizatorach obiektów 331
- 10.2.2. Używanie metod rozszerzających w inicjalizatorach kolekcji 335
- 10.2.3. Kod testów a kod produkcyjny 339
- 10.3. Operator ?. 340
- 10.3.1. Proste i bezpieczne dereferencje właściwości 340
- 10.3.2. Szczegółowe omówienie operatora ?. 341
- 10.3.3. Obsługa porównań logicznych 342
- 10.3.4. Indeksery i operator ?. 344
- 10.3.5. Skuteczne używanie operatora ?. 344
- 10.3.6. Ograniczenia operatora ?. 346
- 10.4. Filtry wyjątków 346
- 10.4.1. Składnia i semantyka filtrów wyjątków 347
- 10.4.2. Ponawianie operacji 352
- 10.4.3. Zapis danych w dzienniku jako efekt uboczny 354
- 10.4.4. Pojedyncze, specyficzne filtry wyjątków 355
- 10.4.5. Dlaczego po prostu nie zgłaszać wyjątków? 355
- Podsumowanie 356
CZĘŚĆ 4. C# 7 I PRZYSZŁE WERSJE 357
Rozdział 11. Łączenie danych z użyciem krotek 359
- 11.1. Wprowadzenie do krotek 360
- 11.2. Literały i typy krotek 361
- 11.2.1. Składnia 361
- 11.2.2. Wnioskowanie nazw elementów w literałach krotek (C# 7.1) 364
- 11.2.3. Krotki jako zbiory zmiennych 365
- 11.3. Typy krotek i konwersje 369
- 11.3.1. Typy literałów krotek 369
- 11.3.2. Konwersje z literałów krotek na typy krotek 371
- 11.3.3. Konwersja między typami krotek 374
- 11.3.4. Zastosowania konwersji 377
- 11.3.5. Sprawdzanie nazw elementów przy dziedziczeniu 377
- 11.3.6. Operatory równości i nierówności (C# 7.3) 378
- 11.4. Krotki w środowisku CLR 379
- 11.4.1. Wprowadzenie do typów System.ValueTuple<...> 379
- 11.4.2. Obsługa nazw elementów 380
- 11.4.3. Implementacje konwersji krotek 381
- 11.4.4. Tekstowe reprezentacje krotek 382
- 11.4.5. Standardowe porównania na potrzeby sprawdzania równości i sortowania 383
- 11.4.6. Strukturalne porównania na potrzeby sprawdzania równości i sortowania 384
- 11.4.7. Krotki jednowartościowe i duże krotki 386
- 11.4.8. Niegeneryczna struktura ValueTuple 387
- 11.4.9. Metody rozszerzające 387
- 11.5. Alternatywy dla krotek 388
- 11.5.1. System.Tuple<...> 388
- 11.5.2. Typy anonimowe 388
- 11.5.3. Typy nazwane 389
- 11.6. Zastosowania i rekomendacje 389
- 11.6.1. Niepubliczne interfejsy API i kod, który można łatwo modyfikować 390
- 11.6.2. Zmienne lokalne 390
- 11.6.3. Pola 392
- 11.6.4. Krotki i typowanie dynamiczne nie współdziałają dobrze ze sobą 393
- Podsumowanie 394
Rozdział 12. Podział krotek i dopasowywanie wzorców 395
- 12.1. Podział krotek 396
- 12.1.1. Podział na nowe zmienne 397
- 12.1.2. Używanie podziału do przypisywania wartości istniejącym zmiennym i właściwościom 399
- 12.1.3. Szczegóły podziału literałów krotek 403
- 12.2. Podział typów innych niż krotki 403
- 12.2.1. Metody instancji odpowiedzialne za podział obiektów 403
- 12.2.2. Odpowiedzialne za podział metody rozszerzające a przeciążanie metod 404
- 12.2.3. Obsługa wywołań Deconstruct w kompilatorze 406
- 12.3. Wprowadzenie do dopasowywania wzorców 407
- 12.4. Wzorce dostępne w C# 7.0 409
- 12.4.1. Wzorce stałych 409
- 12.4.2. Wzorce typów 410
- 12.4.3. Wzorzec var 413
- 12.5. Używanie wzorców razem z operatorem is 414
- 12.6. Używanie wzorców w instrukcjach switch 416
- 12.6.1. Klauzule zabezpieczające 417
- 12.6.2. Zasięg zmiennej ze wzorca w klauzulach case 418
- 12.6.3. Kolejność przetwarzania w instrukcjach switch opartych na wzorcu 420
- 12.7. Przemyślenia na temat zastosowań opisanych mechanizmów 421
- 12.7.1. Wykrywanie możliwości podziału obiektów 422
- 12.7.2. Wykrywanie możliwości dopasowywania wzorców 422
- Podsumowanie 423
Rozdział 13. Zwiększanie wydajności dzięki częstszemu przekazywaniu danych przez referencję 425
- 13.1. Przypomnienie - co wiesz o słowie kluczowym ref? 427
- 13.2. Zmienne lokalne ref i referencyjne zwracane wartości 429
- 13.2.1. Zmienne lokalne ref 430
- 13.2.2. Instrukcja return ref 435
- 13.2.3. Operator warunkowy ?: i wartości z modyfikatorem ref (C# 7.2) 437
- 13.2.4. Modyfikator ref readonly (C# 7.2) 438
- 13.3. Parametry in (C# 7.2) 440
- 13.3.1. Zgodność wstecz 441
- 13.3.2. Zaskakująca modyfikowalność parametrów in - zmiany zewnętrzne 442
- 13.3.3. Przeciążanie metod z użyciem parametrów in 444
- 13.3.4. Wskazówki dotyczące parametrów in 444
- 13.4. Deklarowanie struktur tylko do odczytu (C# 7.2) 446
- 13.4.1. Wprowadzenie - niejawne kopiowanie zmiennych tylko do odczytu 446
- 13.4.2. Modyfikator readonly dla struktur 449
- 13.4.3. Serializowane dane w XML-u są z natury przeznaczone do odczytu i zapisu 450
- 13.5. Metody rozszerzające z parametrami ref i in (C# 7.2) 451
- 13.5.1. Używanie parametrów ref i in w metodach rozszerzających, aby uniknąć kopiowania 451
- 13.5.2. Ograniczenia dotyczące metod rozszerzających z pierwszym parametrem ref lub in 453
- 13.6. Struktury referencyjne (C# 7.2) 454
- 13.6.1. Reguły dotyczące struktur referencyjnych 455
- 13.6.2. Typ Span
i wywołanie stackalloc 456 - 13.6.3. Reprezentacja struktur referencyjnych w kodzie pośrednim 460
- Podsumowanie 461
Rozdział 14. Zwięzły kod w C# 7 463
- 14.1. Metody lokalne 463
- 14.1.1. Dostęp do zmiennych w metodach lokalnych 465
- 14.1.2. Implementowanie metod lokalnych 468
- 14.1.3. Wskazówki dotyczące użytkowania 473
- 14.2. Zmienne out 476
- 14.2.1. Wewnątrzwierszowe deklaracje zmiennych na potrzeby parametrów out 476
- 14.2.2. Zniesione w C# 7.3 ograniczenia dotyczące zmiennych out i zmiennych generowanych we wzorcach 477
- 14.3. Usprawnienia w literałach liczbowych 478
- 14.3.1. Dwójkowe literały całkowitoliczbowe 478
- 14.3.2. Separatory w postaci podkreślenia 479
- 14.4. Wyrażenia throw 480
- 14.5. Literał default (C# 7.1) 481
- 14.6. Argumenty nazwane w dowolnym miejscu listy argumentów (C# 7.2) 482
- 14.7. Dostęp private protected (C# 7.2) 484
- 14.8. Drobne usprawnienia z C# 7.3 484
- 14.8.1. Ograniczenia typów generycznych 484
- 14.8.2. Usprawnienia w wyborze wersji przeciążonych metod 485
- 14.8.3. Atrybuty pól powiązanych z automatycznie implementowanymi właściwościami 486
- Podsumowanie 487
Rozdział 15. C# 8 i kolejne wersje 489
- 15.1. Typy referencyjne przyjmujące wartość null 490
- 15.1.1. Jaki problem rozwiązują typy referencyjne przyjmujące wartość null? 490
- 15.1.2. Zmiana działania typów referencyjnych w kontekście wartości null 491
- 15.1.3. Poznaj typy referencyjne przyjmujące null 492
- 15.1.4. Działanie typów referencyjnych przyjmujących null w czasie kompilacji i w czasie wykonywania kodu 493
- 15.1.5. Operator "a niech to" 496
- 15.1.6. Wrażenia z wprowadzania typów referencyjnych przyjmujących null 498
- 15.1.7. Przyszłe usprawnienia 500
- 15.2. Wyrażenia switch 504
- 15.3. Rekurencyjne dopasowywanie wzorców 506
- 15.3.1. Dopasowywanie z użyciem właściwości we wzorcach 507
- 15.3.2. Wzorce oparte na podziale 507
- 15.3.3. Pomijanie typów we wzorcach 508
- 15.4. Indeksy i przedziały 509
- 15.4.1. Typy i literały Index i Range 510
- 15.4.2. Stosowanie indeksów i przedziałów 511
- 15.5. Lepsza integracja asynchroniczności 512
- 15.5.1. Asynchroniczne zwalnianie zasobów z użyciem instrukcji using await 512
- 15.5.2. Asynchroniczne iteracje z użyciem instrukcji foreach await 514
- 15.5.3. Asynchroniczne iteratory 517
- 15.6. Funkcje, które nie znalazły się w wersji zapoznawczej 518
- 15.6.1. Domyślne metody interfejsu 518
- 15.6.2. Typy rekordowe 520
- 15.6.3. Krótki opis jeszcze innych funkcji 521
- 15.7. Udział w pracach 523
- Wnioski 523
Dodatek A. Funkcje języka wprowadzone w poszczególnych wersjach 525
Kategoria: | Programowanie |
Zabezpieczenie: |
Watermark
|
ISBN: | 978-83-283-6030-3 |
Rozmiar pliku: | 4,9 MB |