Darmowy fragment publikacji:
Tytuł oryginału: C# in Depth, Second Edition
Tłumaczenie: Janusz Grabis
Projekt okładki: Studio Gravite / Olsztyn
Obarek, Pokoński, Pazdrijowski, Zaprucki
ISBN: 978-83-246-3921-2
Original edition copyright © 2011 by Manning Publications Co.
All rights reserved.
Polish edition copyright © 2012 by HELION SA.
All rights reserved.
All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means,
electronic or mechanical, including photocopying, recording or by any information storage retrieval system,
without permission from the Publisher.
Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej
publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną,
fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje
naruszenie praw autorskich niniejszej publikacji.
Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich
właścicieli.
Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte
w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich
wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz
Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe
z wykorzystania informacji zawartych w książce.
Wydawnictwo HELION
ul. Kościuszki 1c, 44-100 GLIWICE
tel. 32 231 22 19, 32 230 98 63
e-mail: helion@helion.pl
WWW: http://helion.pl (księgarnia internetowa, katalog książek)
Drogi Czytelniku!
Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres
http://helion.pl/user/opinie/cshop2
Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.
Printed in Poland.
• Kup książkę
• Poleć książkę
• Oceń książkę
• Księgarnia internetowa
• Lubię to! » Nasza społeczność
Spis treĂci
7
Spis treĂci
17
19
21
23
Przedmowa
WstÚp
PodziÚkowania
O ksiÈĝce
CzÚĂÊ I
1. NieustajÈca metamorfoza C#
Przygotowanie do wyprawy
31
33
1.1. Na poczÈtek prosty typ danych ................................................................................................... 34
1.1.1. Typ Product w C# 1 ....................................................................................................... 35
1.1.2. Kolekcje o mocnym typie w C# 2 ................................................................................. 36
1.1.3. WïaĂciwoĂci implementowane automatycznie w C# 3 ................................................ 37
1.1.4. Argumenty nazwane w C# 4 ......................................................................................... 38
1.2. Sortowanie i filtrowanie .............................................................................................................. 39
1.2.1. Sortowanie produktów po nazwie .................................................................................. 40
1.2.2. Wyszukiwanie elementów w kolekcjach ....................................................................... 43
1.3. Obsïuga braku danych ................................................................................................................. 44
1.3.1. Reprezentacja nieznanej ceny ........................................................................................ 45
1.3.2. Parametry opcjonalne i wartoĂci domyĂlne ................................................................... 46
1.4. Wprowadzenie do LINQ ............................................................................................................. 46
1.4.1. Wyraĝenia kwerendowe i zapytania wewnÈtrzprocesowe ........................................... 47
1.4.2. Wykonywanie zapytañ na XML-u ................................................................................. 48
1.4.3. LINQ dla SQL-a ............................................................................................................. 49
8
SPIS TREĝCI
2. Rdzeñ systemu — C# 1
1.7.
1.5. COM i typy dynamiczne .............................................................................................................. 50
1.5.1. Uproszczenie wspóïpracy z COM ................................................................................. 50
1.5.2. Wspóïpraca z jÚzykiem dynamicznym ........................................................................... 51
1.6. Analiza zawartoĂci Ărodowiska .NET ......................................................................................... 52
1.6.1.
JÚzyk C# ......................................................................................................................... 53
1.6.2. ¥rodowisko wykonania ................................................................................................... 53
1.6.3. Biblioteki Ărodowiska ...................................................................................................... 54
Jak zmieniÊ Twój kod w kod doskonaïy? ................................................................................... 54
1.7.1. Prezentacja peïnych programów w formie fragmentów kodu ...................................... 55
1.7.2. Kod dydaktyczny nie jest kodem produkcyjnym .......................................................... 56
1.7.3. Twój nowy najlepszy przyjaciel — specyfikacja jÚzyka ................................................ 56
1.8. Podsumowanie .............................................................................................................................. 57
59
2.1. Delegaty ........................................................................................................................................ 60
2.1.1. Przepis na prosty delegat ................................................................................................ 61
2.1.2. Èczenie i usuwanie delegatów ..................................................................................... 66
2.1.3. Dygresja na temat zdarzeñ ............................................................................................. 67
2.1.4. Podsumowanie delegatów .............................................................................................. 68
2.2. Charakterystyka systemu typów ................................................................................................. 69
2.2.1. Miejsce C# w Ăwiecie systemów typów ........................................................................ 69
2.2.2. Kiedy system typów C# 1 jest niedostatecznie bogaty? .............................................. 73
2.2.3. Podsumowanie charakterystyki systemu typów ............................................................ 75
2.3. Typy wartoĂciowe i referencyjne ............................................................................................... 76
2.3.1. WartoĂci i referencje w rzeczywistym Ăwiecie .............................................................. 76
2.3.2. Podstawy typów referencyjnych i wartoĂciowych ........................................................ 77
2.3.3. Obalanie mitów ............................................................................................................... 79
2.3.4. Opakowywanie i odpakowywanie .................................................................................. 81
2.3.5. Podsumowanie typów wartoĂciowych i referencyjnych ............................................... 82
2.4. WiÚcej niĝ C# 1 — nowe cechy na solidnym fundamencie .................................................... 83
2.4.1. Cechy zwiÈzane z delegatami ........................................................................................ 83
2.4.2. Cechy zwiÈzane z systemem typów ............................................................................... 85
2.4.3. Cechy zwiÈzane z typami wartoĂciowymi ..................................................................... 87
2.5. Podsumowanie .............................................................................................................................. 88
CzÚĂÊ II C# 2 — rozwiÈzanie problemów C# 1
3.
89
Parametryzowanie typów i metod
91
3.1. Czemu potrzebne sÈ typy generyczne? ...................................................................................... 92
3.2. Proste typy generyczne do codziennego uĝycia ........................................................................ 94
3.2.1. Nauka przez przykïad — sïownik typu generycznego ................................................. 94
3.2.2. Typy generyczne i parametry typów ............................................................................. 96
3.2.3. Metody generyczne i czytanie deklaracji generycznych ............................................ 100
3.3. Wkraczamy gïÚbiej .................................................................................................................... 103
3.3.1. Ograniczenia typów ...................................................................................................... 104
3.3.2.
Interfejs argumentów typu dla metod generycznych ................................................. 109
Implementowanie typów generycznych ...................................................................... 110
3.3.3.
3.4. Zaawansowane elementy typów generycznych ....................................................................... 116
3.4.1. Pola i konstruktory statyczne ....................................................................................... 117
3.4.2.
Jak kompilator JIT traktuje typy generyczne .............................................................. 119
Spis treĂci
9
4. Wyraĝanie „niczego” przy uĝyciu typów nullowalnych
3.4.3.
Iteracja przy uĝyciu typów generycznych ................................................................... 121
3.4.4. Refleksja i typy generyczne .......................................................................................... 123
3.5. Ograniczenia typów generycznych C# i innych jÚzyków ...................................................... 128
3.5.1. Brak wariancji typów generycznych ............................................................................ 128
3.5.2. Brak ograniczeñ operatorów lub ograniczeñ „numerycznych” .................................. 133
3.5.3. Brak generycznych wïaĂciwoĂci, indekserów i innych elementów typu ................... 135
3.5.4. Porównanie z C++ ...................................................................................................... 136
3.5.5. Porównanie z typami generycznymi Javy .................................................................... 137
3.6. Podsumowanie ............................................................................................................................ 139
141
4.1. Co robisz, kiedy zwyczajnie nie masz wartoĂci? ..................................................................... 142
4.1.1. Czemu zmienne typu wartoĂciowego nie mogÈ zawieraÊ null? ................................. 142
4.1.2. Metody reprezentacji wartoĂci null w C# 1 ............................................................... 143
4.2. System.Nullable T i System.Nullable ................................................................................. 145
4.2.1. Wprowadzenie Nullable T ..................................................................................... 146
4.2.2. Opakowywanie i odpakowywanie Nullable T ....................................................... 149
4.2.3. RównoĂÊ instancji Nullable T ................................................................................. 150
4.2.4. Wsparcie ze strony niegenerycznej klasy Nullable .................................................... 151
4.3. Skïadnia C# 2 dla typów nullowalnych ................................................................................... 152
4.3.1. Modyfikator ? ................................................................................................................ 152
4.3.2. Przypisania i porównania z null ................................................................................... 154
4.3.3. Konwersje i operatory nullowalne ............................................................................... 156
4.3.4. Logika typów nullowalnych ......................................................................................... 159
4.3.5. Stosowanie operatora as z typami nullowalnymi ........................................................ 161
4.3.6. Nullowy operator koalescencyjny ................................................................................ 161
4.4. Nowatorskie zastosowania typów nullowalnych ..................................................................... 164
4.4.1. Testowanie operacji bez parametrów zwrotnych ........................................................ 165
4.4.2. Bezbolesne porównania przy uĝyciu nullowalnego operatora koalescencyjnego ..... 167
4.5. Podsumowanie ............................................................................................................................ 169
Przyspieszone delegaty
171
5.1. Poĝegnanie z dziwacznÈ skïadniÈ delegatów .......................................................................... 173
5.2. Konwersja grupy metod ............................................................................................................ 174
5.3. Kowariancja i kontrawariancja ................................................................................................ 176
5.3.1. Kontrawariancja parametrów delegatów ..................................................................... 176
5.3.2. Kowariancja typu zwracanego delegata ....................................................................... 178
5.3.3. Maïe ryzyko niekompatybilnoĂci ................................................................................. 179
5.4. Akcje delegatów tworzone w miejscu przy uĝyciu metod anonimowych ............................. 180
5.4.1. Rozpoczynamy prosto — operujÈc na parametrach ................................................... 181
5.4.2. Zwracanie wartoĂci z metod anonimowych ................................................................. 183
Ignorowanie parametrów typu ..................................................................................... 185
5.4.3.
5.5. Przechwytywanie zmiennych w metodach anonimowych ..................................................... 186
5.5.1. Definicja domkniÚcia i róĝnych typów zmiennych ..................................................... 187
5.5.2. Analiza zachowania zmiennych przechwyconych ....................................................... 188
5.5.3.
Jaki cel majÈ zmienne przechwycone? ........................................................................ 189
5.5.4. Przedïuĝone ĝycie zmiennych przechwyconych ......................................................... 190
5.5.5.
Instancje zmiennej lokalnej .......................................................................................... 192
5.5.6. Mieszanka zmiennych wspóïdzielonych i odrÚbnych ................................................. 194
5.5.7. Wskazówki odnoĂnie do zmiennych przechwyconych i podsumowanie ................... 196
5.6. Podsumowanie ............................................................................................................................ 197
5.
10
6.
7.
SPIS TREĝCI
Implementowanie iteratorów w prosty sposób
199
6.1. C# 1 — udrÚka rÚcznego pisania iteratorów ......................................................................... 201
6.2. C# 2 — proste iteratory z wyraĝeniami yield ........................................................................ 204
6.2.1. Wprowadzenie do uproszczeñ iteratorów i wyraĝenia yield return .......................... 204
6.2.2. Wizualizacja toku wykonania iteratora ........................................................................ 206
6.2.3.
Zaawansowany tok wykonania iteratora ...................................................................... 208
6.2.4. Dziwactwa w implementacji ........................................................................................ 211
6.3. Przykïady z ĝycia ........................................................................................................................ 213
Iterowanie po datach w harmonogramie ..................................................................... 213
6.3.1.
6.3.2.
Iterowanie po wierszach pliku ..................................................................................... 214
6.3.3. Leniwe filtrowanie elementów z uĝyciem uproszczenia iteratora i predykatu ......... 217
6.4. Pseudosynchroniczny kod z uĝyciem biblioteki CCR ............................................................ 219
6.5. Podsumowanie ............................................................................................................................ 222
Pozostaïe cechy C# 2
225
7.1. Typy czÚĂciowe ........................................................................................................................... 227
7.1.1. Tworzenie typu skïadajÈcego siÚ z kilku plików ......................................................... 227
7.1.2. Uĝycie typów czÚĂciowych ........................................................................................... 229
7.1.3. Metody czÚĂciowe — tylko w C# 3 ............................................................................. 231
7.2. Klasy statyczne ........................................................................................................................... 233
7.3. Niezaleĝny poziom dostÚpu do getterów i setterów wïaĂciwoĂci .......................................... 235
7.4. Aliasy przestrzeni nazw ............................................................................................................. 237
7.4.1. Kwalifikowanie aliasów przestrzeni nazw ................................................................... 238
7.4.2. Aliasy globalnej przestrzeni nazw ................................................................................ 239
7.4.3. Aliasy zewnÚtrzne ......................................................................................................... 240
7.5. Dyrektywy pragma ..................................................................................................................... 241
7.5.1. Pragmy ostrzeĝeñ .......................................................................................................... 242
7.5.2. Pragmy sum kontrolnych .............................................................................................. 243
7.6. Bufory o staïym rozmiarze w kodzie niezarzÈdzanym ........................................................... 243
7.7. UdostÚpnianie wybranych elementów innym moduïom ........................................................ 245
7.7.1. Zaprzyjaěnione moduïy w prostym przypadku ........................................................... 246
7.7.2. Do czego warto uĝywaÊ InternalsVisibleTo? .............................................................. 247
InternalsVisibleTo i moduïy podpisane ....................................................................... 247
7.7.3.
7.8. Podsumowanie ............................................................................................................................ 248
CzÚĂÊ III C# 3 — rewolucja w metodzie programowania
8. Redukcja nadmiarowoĂci przez zmyĂlny kompilator
251
253
8.1. WïaĂciwoĂci implementowane automatycznie ........................................................................ 255
8.2. Zmienne lokalne o typie niejawnym ........................................................................................ 257
8.2.1. Zastosowanie var do deklarowania zmiennych lokalnych .......................................... 257
8.2.2. Ograniczenia w typach niejawnych ............................................................................. 259
8.2.3. Zalety i wady typów niejawnych .................................................................................. 260
8.2.4. Zalecenia ....................................................................................................................... 261
8.3. Uproszczona inicjalizacja .......................................................................................................... 262
8.3.1. Definicja prostych typów ............................................................................................. 262
8.3.2. Ustawianie prostych wïaĂciwoĂci ................................................................................. 263
8.3.3. Ustawianie wïaĂciwoĂci obiektów zagnieĝdĝonych .................................................... 265
8.3.4.
Inicjalizatory kolekcji .................................................................................................... 266
8.3.5. Zastosowanie inicjalizatorów ........................................................................................ 269
Spis treĂci
11
9. Wyraĝenia lambda i drzewa wyraĝeñ
8.4. Tablice o typie niejawnym ........................................................................................................ 270
8.5. Typy anonimowe ........................................................................................................................ 272
8.5.1. Pierwsze spotkania z gatunkiem anonimowym ........................................................... 272
8.5.2. CzÚĂci skïadowe typów anonimowych ......................................................................... 274
8.5.3.
Inicjalizatory odwzorowujÈce ...................................................................................... 275
Jaki to ma sens? ............................................................................................................. 276
8.5.4.
8.6. Podsumowanie ............................................................................................................................ 277
279
9.1. Wyraĝenia lambda i delegaty ................................................................................................... 281
9.1.1. Przygotowanie — wprowadzenie delegatów typu Func ... .................................. 281
9.1.2. Pierwsze przeksztaïcenie na wyraĝenie lambda ......................................................... 282
9.1.3. Uĝywanie pojedynczego wyraĝenia jako ciaïa ............................................................. 283
9.1.4. Lista parametrów o typie niejawnym .......................................................................... 284
9.1.5. Skrót dla pojedynczego parametru .............................................................................. 284
9.2. Proste przykïady uĝycia List T i zdarzeñ ........................................................................... 286
9.2.1. Filtrowanie, sortowanie i operacje na listach .............................................................. 286
9.2.2. Logowanie w metodach obsïugi zdarzeñ ..................................................................... 288
9.3. Drzewa wyraĝeñ ......................................................................................................................... 289
9.3.1. Budowanie drzew wyraĝeñ w sposób programistyczny ............................................. 289
9.3.2. Kompilowanie drzew wyraĝeñ do postaci delegatów ................................................. 291
9.3.3. Konwersja wyraĝeñ lambda C# na drzewa wyraĝeñ .................................................. 292
9.3.4. Drzewa wyraĝeñ w sercu LINQ .................................................................................. 296
9.3.5. Drzewa wyraĝeñ poza LINQ ....................................................................................... 297
9.4. Zmiany we wnioskowaniu typów i rozwiÈzywaniu przeciÈĝeñ ............................................. 299
9.4.1. Powód do zmiany — usprawnienie wywoïañ metod generycznych .......................... 300
9.4.2. Wnioskowanie typu zwracanego funkcji anonimowych ............................................. 301
9.4.3. Dwufazowe wnioskowanie typu ................................................................................... 302
9.4.4. Wybieranie odpowiedniego przeciÈĝenia metody ...................................................... 306
9.4.5. Podsumowanie wnioskowania typów i rozwiÈzywania przeciÈĝeñ ............................ 308
9.5. Podsumowanie ............................................................................................................................ 308
311
10.1. ¿ycie przed metodami rozszerzajÈcymi .................................................................................. 312
10.2. Skïadnia metod rozszerzajÈcych .............................................................................................. 315
10.2.1. Deklarowanie metod rozszerzajÈcych ......................................................................... 315
10.2.2. Wywoïywanie metod rozszerzajÈcych ......................................................................... 316
10.2.3. Wykrywanie metod rozszerzajÈcych ............................................................................ 318
10.2.4. Wywoïanie metody na pustej referencji ...................................................................... 319
10.3. Metody rozszerzajÈce w .NET 3.5 ............................................................................................ 321
10.3.1. Pierwsze kroki z Enumerable ...................................................................................... 321
10.3.2. Filtrowanie z uĝyciem Where i spinania wywoïañ metod ......................................... 323
10.3.3. Antrakt: czy metody Where nie widzieliĂmy juĝ wczeĂniej? ..................................... 325
10.3.4. Projekcja przy uĝyciu metody Select i typów anonimowych ..................................... 326
10.3.5. Sortowanie przy uĝyciu OrderBy ................................................................................. 327
10.3.6. Przykïady logiki biznesowej z uĝyciem ïañcuchowania ............................................. 328
10.4. Wskazówki i uwagi odnoĂnie do uĝycia ................................................................................... 330
10.4.1. „Rozszerzanie Ăwiata” i wzbogacanie interfejsów ....................................................... 330
10.4.2. Pïynne interfejsy ........................................................................................................... 331
10.4.3. Rozwaĝne uĝycie metod rozszerzajÈcych .................................................................... 332
10.5. Podsumowanie ............................................................................................................................ 334
10. Metody rozszerzajÈce
12
SPIS TREĝCI
11. Wyraĝenia kwerendowe i LINQ dla Obiektów
335
11.1. Wprowadzenie do LINQ ........................................................................................................... 336
11.1.1. Podstawowe koncepcje w LINQ ................................................................................. 336
11.1.2. Definiowanie przykïadowego modelu danych ............................................................ 341
11.2. Prosty poczÈtek — wybieranie elementów .............................................................................. 343
11.2.1. Rozpoczynanie od ěródïa i koñczenie na selekcji ....................................................... 343
11.2.2. Translacja kompilatora jako podstawa wyraĝeñ kwerendowych ................................ 344
11.2.3. Zmienne zakresu i projekcje nietrywialne .................................................................. 347
11.2.4. Cast, OfType i zmienne zakresu o typie jawnym ........................................................ 349
11.3. Filtrowanie i porzÈdkowanie sekwencji .................................................................................. 351
11.3.1. Filtrowanie przy uĝyciu klauzuli where ...................................................................... 351
11.3.2. Zdegenerowane wyraĝenia kwerendowe .................................................................... 352
11.3.3. PorzÈdkowanie przy uĝyciu klauzuli orderby ............................................................. 353
11.4. Klauzule let i identyfikatory przezroczyste ............................................................................. 356
11.4.1. Wprowadzenie do wykonania poĂredniego z uĝyciem let .......................................... 356
11.4.2. Identyfikatory przezroczyste ........................................................................................ 357
11.5. ZïÈczenia ..................................................................................................................................... 359
11.5.1. ZïÈczenia wewnÚtrzne korzystajÈce z klauzul join ...................................................... 359
11.5.2. ZïÈczenia grupowe z uĝyciem klauzul join … into ..................................................... 363
11.5.3. ZïÈczenia krzyĝowe i spïaszczanie sekwencji
12. LINQ — nie tylko kolekcje
przy uĝyciu wielokrotnych klauzul from ..................................................................... 366
11.6. Grupowania i kontynuacje ........................................................................................................ 369
11.6.1. Grupowanie przy uĝyciu klauzuli group ... by ............................................................ 369
11.6.2. Kontynuacje zapytañ .................................................................................................... 373
11.7. Wybór pomiÚdzy wyraĝeniami kwerendowymi a notacjÈ kropkowÈ ................................... 375
11.7.1. Operacje wymagajÈce notacji kropkowej .................................................................... 376
11.7.2. Wyraĝenia kwerendowe, dla których prostszym rozwiÈzaniem
moĝe siÚ okazaÊ notacja kropkowa ............................................................................... 377
11.7.3. Gdzie wyraĝenia kwerendowe lĂniÈ? ........................................................................... 377
11.8. Podsumowanie ............................................................................................................................ 379
381
12.1. Odpytywanie bazy danych przez LINQ dla SQL-a ................................................................ 382
12.1.1. Zaczynamy od bazy danych i modelu .......................................................................... 383
12.1.2. Zapytania wstÚpne ........................................................................................................ 385
12.1.3. Zapytania wymagajÈce zïÈczeñ .................................................................................... 388
12.2. Translacje przy uĝyciu IQueryable i IQueryProvider ........................................................... 390
12.2.1. Wprowadzenie do IQueryable T i zwiÈzanych z nim interfejsów ....................... 391
12.2.2. Prototyp — implementacja interfejsów wykonujÈca wpisy w dzienniku .................. 393
12.2.3. Spajanie wszystkiego razem — metody rozszerzajÈce typu Queryable .................... 395
12.2.4. Udawany dostawca w dziaïaniu ................................................................................... 397
12.2.5. Podsumowanie IQueryable .......................................................................................... 398
12.3. Interfejsy zaprzyjaěnione z LINQ i LINQ dla XML-a .......................................................... 399
12.3.1. Rdzenne typy LINQ dla XML-a .................................................................................. 399
12.3.2. Konstrukcja deklaratywna ............................................................................................ 401
12.3.3. Zapytania na pojedynczych wÚzïach ............................................................................ 404
12.3.4. Operatory zapytañ spïaszczonych ................................................................................ 406
12.3.5. Praca w harmonii z LINQ ............................................................................................ 407
Spis treĂci
13
12.4. ZastÈpienie LINQ dla Obiektów Równolegïym LINQ .......................................................... 408
12.4.1. KreĂlenie zbioru Mandelbrota przez pojedynczy wÈtek ............................................ 409
12.4.2. Wprowadzenie ParallelEnumerable, ParallelQuery i AsParallel ............................... 410
12.4.3. PodkrÚcanie zapytañ równolegïych ............................................................................. 411
12.5. Odwrócenie modelu zapytania przy uĝyciu LINQ dla Rx ..................................................... 413
12.5.1. IObservable T i IObserver T ............................................................................ 414
12.5.2. Zaczynamy (ponownie) ïagodnie .................................................................................. 416
12.5.3. Odpytywanie obiektów obserwowalnych .................................................................... 417
12.5.4. Jaki to wszystko ma sens? ............................................................................................. 419
12.6. Rozszerzanie LINQ dla Obiektów ........................................................................................... 420
12.6.1. Wytyczne odnoĂnie do projektu i implementacji ....................................................... 421
12.6.2. Proste rozszerzenie — wybieranie losowego elementu ............................................. 422
12.7. Podsumowanie ............................................................................................................................ 424
CzÚĂÊ IV C# 4 — dobra wspóïpraca z innymi interfejsami
13. Maïe zmiany dla uproszczenia kodu
427
429
13.1. Parametry opcjonalne i argumenty nazwane .......................................................................... 430
13.1.1. Parametry opcjonalne ................................................................................................... 430
13.1.2. Argumenty nazwane ..................................................................................................... 437
13.1.3. Zïoĝenie dwóch cech w caïoĂÊ ..................................................................................... 441
13.2. Usprawnienia we wspóïpracy z COM ...................................................................................... 446
13.2.1. Horror automatyzacji Worda przed C# 4 ................................................................... 446
13.2.2. Zemsta parametrów opcjonalnych i argumentów nazwanych .................................... 447
13.2.3. Kiedy parametr ref nie jest parametrem ref? .............................................................. 448
13.2.4. Wywoïywanie indekserów nazwanych ........................................................................ 449
13.2.5. Èczenie gïównych bibliotek COM-owych ................................................................. 451
13.3. Wariancja typów generycznych dla interfejsów i delegatów ................................................ 453
13.3.1. Typy wariancji: kowariancja i kontrawariancja ........................................................... 454
13.3.2. Uĝycie wariancji w interfejsach ................................................................................... 455
13.3.3. Zastosowanie wariancji w delegatach .......................................................................... 458
13.3.4. Zïoĝone sytuacje ............................................................................................................ 459
13.3.5. Restrykcje i uwagi ......................................................................................................... 461
13.4. Mikroskopijne zmiany w blokadach i zdarzeniach w formie pól .......................................... 465
13.4.1. Solidne blokowanie ....................................................................................................... 465
13.4.2. Zmiany w zdarzeniach w formie pól ............................................................................ 467
13.5. Podsumowanie ............................................................................................................................ 467
469
14.1. Co? Kiedy? Dlaczego? Jak? ....................................................................................................... 471
14.1.1. Czym sÈ typy dynamiczne? .......................................................................................... 471
14.1.2. Kiedy typy dynamiczne sÈ uĝyteczne i dlaczego? ....................................................... 472
14.1.3. W jaki sposób C# zapewnia typy dynamiczne? ......................................................... 474
14.2. PiÚciominutowy przewodnik po typie dynamic ...................................................................... 474
14.3. Przykïady uĝycia typów dynamicznych ................................................................................... 477
14.3.1. COM w ogólnoĂci i Microsoft Office w szczególnoĂci ............................................... 477
14.3.2. JÚzyki dynamiczne, takie jak IronPython .................................................................... 479
14.3.3. Typy dynamiczne w kodzie caïkowicie zarzÈdzanym ................................................. 484
14.4. ZaglÈdamy pod maskÚ ............................................................................................................... 490
14.4.1. Wprowadzenie do DLR ............................................................................................... 491
14.4.2. Fundamentalne koncepcje DLR .................................................................................. 493
14. Dynamiczne wiÈzanie w jÚzyku statycznym
14
SPIS TREĝCI
15. JaĂniejsze wyraĝanie kodu przy uĝyciu kontraktów kodu
14.4.3. Jak kompilator C# obsïuguje sïowo dynamic? ........................................................... 496
14.4.4. Kompilator C# staje siÚ jeszcze sprytniejszy ............................................................. 500
14.4.5. Ograniczenia kodu dynamicznego ............................................................................... 503
14.5. Implementacja zachowania dynamicznego ............................................................................. 506
14.5.1. Uĝycie klasy ExpandoObject ....................................................................................... 506
14.5.2. Uĝycie klasy DynamicObject ....................................................................................... 511
14.5.3. Implementacja IDynamicMetaObjectProvider .......................................................... 518
14.6. Podsumowanie ............................................................................................................................ 522
523
15.1. ¿ycie przed kontraktami kodu .................................................................................................. 525
15.2. Wprowadzenie do kontraktów kodu ........................................................................................ 527
15.2.1. Warunki wstÚpne .......................................................................................................... 529
15.2.2. Warunki koñcowe ......................................................................................................... 530
15.2.3. Inwarianty ..................................................................................................................... 531
15.2.4. Asercje i zaïoĝenia ........................................................................................................ 533
15.2.5. Kontrakty legacyjne ...................................................................................................... 534
15.3. Przepisywanie kodu binarnego przez ccrewrite i ccrefgen ................................................... 536
15.3.1. Proste przepisywanie .................................................................................................... 536
15.3.2. Dziedziczenie kontraktów ............................................................................................ 538
15.3.3. Referencyjne moduïy kontraktów ................................................................................ 541
15.3.4. Zachowanie w przypadku poraĝki ................................................................................ 543
15.4. Sprawdzanie statyczne .............................................................................................................. 545
15.4.1. Wprowadzenie do analizy statycznej ........................................................................... 545
15.4.2. ZobowiÈzania niejawne ................................................................................................ 548
15.4.3. Selektywne wïÈczanie opcji .......................................................................................... 551
15.5. Dokumentowanie kodu przy uĝyciu ccdocgen ........................................................................ 554
15.6. Kontrakty w praktyce ................................................................................................................ 556
15.6.1. Filozofia — czym jest kontrakt? ................................................................................... 557
15.6.2. Jak mam zaczÈÊ? ........................................................................................................... 558
15.6.3. Opcje, wszÚdzie opcje .................................................................................................. 559
15.7. Podsumowanie ............................................................................................................................ 562
565
16.1. C# — poïÈczenie tradycji z nowoczesnoĂciÈ .......................................................................... 566
16.2. Spotkanie .NET z informatykÈ ................................................................................................. 567
16.3. ¥wiat informatyki ....................................................................................................................... 568
16.4. Poĝegnanie .................................................................................................................................. 569
571
573
A.1. Agregacja .................................................................................................................................... 574
A.2. Konkatenacja .............................................................................................................................. 575
A.3. Konwersja ................................................................................................................................... 575
A.4. Operatory jednoelementowe .................................................................................................... 577
A.5. RównoĂÊ ...................................................................................................................................... 578
A.6. Generacja .................................................................................................................................... 579
A.7. Grupowanie ................................................................................................................................ 580
A.8. ZïÈczenia ..................................................................................................................................... 580
A.9. Partycjonowanie ......................................................................................................................... 582
Dodatki
A Standardowe operatory kwerendowe LINQ
16. DokÈd teraz?
Spis treĂci
15
B Kolekcje generyczne w .NET
A.10. Projekcja ..................................................................................................................................... 582
A.11. Kwantyfikatory ........................................................................................................................... 583
A.12. Filtrowanie .................................................................................................................................. 584
A.13. Operatory bazujÈce na zbiorach .............................................................................................. 584
A.14. Sortowanie .................................................................................................................................. 585
587
B.1.
Interfejsy ..................................................................................................................................... 588
B.2. Listy ............................................................................................................................................. 590
B.2.1. List T ........................................................................................................................ 590
B.2.2. Tablice ........................................................................................................................... 591
B.2.3. LinkedList T ............................................................................................................ 592
B.2.4. Collection T , BindingList T , ObservableCollection T
C Podsumowanie wersji Ărodowisk .NET
i KeyedCollection TKey, TItem ............................................................................. 593
B.2.5. ReadOnlyCollection T i ReadOnlyObservableCollection T ........................... 594
B.3. Sïowniki ....................................................................................................................................... 594
B.3.1. Dictionary TKey, TValue ........................................................................................ 594
B.3.2. SortedList TKey, TValue i SortedDictionary TKey, TValue .......................... 595
B.4. Zbiory .......................................................................................................................................... 596
B.4.1. HashSet T ................................................................................................................ 597
B.4.2. SortedSet T (.NET 4) .............................................................................................. 597
B.5. Queue T i Stack T ........................................................................................................... 598
B.5.1. Queue T ................................................................................................................... 598
B.5.2. Stack T ..................................................................................................................... 598
B.6. Kolekcje konkurencyjne (.NET 4) ............................................................................................ 598
B.6.1.
IProducerConsumerCollection T i BlockingCollection T .............................. 599
B.6.2. ConcurrentBag T , ConcurrentQueue T , ConcurrentStack T ................... 600
B.6.3. ConcurrentDictionary TKey, TValue .................................................................... 600
B.7. Podsumowanie ............................................................................................................................ 600
603
C.1. Gïówne wersje dystrybucyjne Ărodowiska typu desktop ....................................................... 604
C.2. Cechy jÚzyka C# ........................................................................................................................ 605
C.2.1. C# 2.0 ............................................................................................................................ 605
C.2.2. C# 3 ............................................................................................................................... 605
C.2.3. C# 4.0 ............................................................................................................................ 606
C.3. Biblioteki Ărodowiska ................................................................................................................. 606
.NET 2.0 ........................................................................................................................ 606
.NET 3.0 ........................................................................................................................ 606
.NET 3.5 ........................................................................................................................ 607
.NET 4 ........................................................................................................................... 607
C.4. Cechy Ărodowiska uruchomieniowego (CLR) ......................................................................... 608
C.4.1. CLR 2.0 ......................................................................................................................... 608
C.4.2. CLR 4.0 ......................................................................................................................... 609
C.5. Inne rodzaje Ărodowiska uruchomieniowego .......................................................................... 609
C.5.1. Compact Framework .................................................................................................... 609
C.5.2. Silverlight ...................................................................................................................... 610
C.5.3. Micro Framework ......................................................................................................... 611
C.6. Podsumowanie ............................................................................................................................ 611
613
C.3.1.
C.3.2.
C.3.3.
C.3.4.
Skorowidz
16
SPIS TREĝCI
Parametryzowanie
typów i metod
Ten rozdziaá omawia:
i typy i metody generyczne,
i interfejs typów dla metod generycznych,
i ograniczenia typów,
i refleksjĊ i typy generyczne,
i zachowanie Ğrodowiska CLR,
i ograniczenia typów generycznych,
i porównanie z innymi jĊzykami.
92
ROZDZIAà 3
Parametryzowanie typów i metod
Oto prawdziwa historia1: pewnego dnia ja i moja ĝona robiliĂmy cotygodniowe zakupy.
Tuĝ przed naszym wyjazdem usïyszaïem pytanie, czy mam listÚ. Potwierdziïem, ĝe mam
listÚ, i pojechaliĂmy. Dopiero kiedy byliĂmy juĝ w sklepie, na jaw wyszïa nasza pomyïka.
Moja ĝona pytaïa o listÚ zakupów, podczas gdy ja wziÈïem ze sobÈ listÚ zmyĂlnych
cech C# 2. Sprzedawca byï trochÚ zdziwiony, kiedy zapytaliĂmy go, czy nie ma przypad-
kiem do sprzedania trochÚ metod anonimowych.
GdybyĂmy tylko mogli wyraziÊ siÚ trochÚ jaĂniej! Gdyby tylko moja ĝona mogïa
w jakiĂ sposób przekazaÊ mi, ĝe chce, abym wziÈï ze sobÈ listÚ rzeczy, które chcemy
kupiÊ! GdybyĂmy tylko mieli typy generyczne...
Dla wiÚkszoĂci programistów typy generyczne stanowiÈ najwaĝniejszÈ nowÈ cechÚ
C# 2. PoprawiajÈ wydajnoĂÊ, sprawiajÈ, ĝe kod jest bardziej ekspresyjny, oraz prze-
noszÈ sporÈ dawkÚ zabezpieczeñ z czasu wykonania do czasu kompilacji. W najwiÚk-
szym skrócie typy generyczne pozwalajÈ na parametryzowanie typów i metod. Tak jak
zwyczajne wywoïania metod posiadajÈ parametry wyraĝajÈce wartoĂci przekazywane
do Ărodka, tak typy generyczne posiadajÈ parametry okreĂlajÈce, jakich typów uĝyÊ do
ich konstrukcji. Brzmi to trochÚ mgliĂcie — jeĂli do tej pory nie miaïeĂ do czynienia
z typami generycznymi, byÊ moĝe bÚdziesz siÚ musiaï dïuĝej zatrzymaÊ przy tym tema-
cie. MogÚ siÚ jednak zaïoĝyÊ, ĝe kiedy zrozumiesz podstawowÈ ideÚ, pokochasz typy
generyczne.
W tym rozdziale zajmiemy siÚ uĝyciem typów i metod generycznych oferowanych
przez Ărodowisko lub biblioteki innych dostawców, a takĝe omówimy, jak napisaÊ wïasne.
Po drodze dowiemy siÚ, jak typy generyczne wspóïdziaïajÈ z wywoïaniami refleksyjnymi
interfejsu programistycznego, oraz poznamy kilka detali odnoĂnie do sposobu obsïugi
typów generycznych przez Ărodowisko wykonawcze. Na koniec rozdziaïu wspomnÚ
o kilku najczÚĂciej spotykanych ograniczeniach typów generycznych z moĝliwymi
obejĂciami oraz porównam typy generyczne C# z podobnymi mechanizmami w innych
jÚzykach programowania.
Na poczÈtku musimy jednak zrozumieÊ problemy, jakie staïy siÚ podstawÈ do opra-
cowania typów generycznych.
3.1. Czemu potrzebne są typy generyczne?
Jeĝeli posiadasz w swoich zasobach kod napisany przy uĝyciu C# 1, przyjrzyj mu siÚ
i policz rzutowania — szczególnie w kodzie, który intensywnie korzysta z kolekcji. Nie
zapominaj, ĝe pod niemal kaĝdÈ pÚtlÈ foreach kryje siÚ niejawne rzutowanie. Kiedy
uĝywasz typów zaprojektowanych do pracy z wieloma róĝnymi typami danych, nieunik-
nionÈ konsekwencjÈ jest duĝa liczba rzutowañ — cichego sposobu informowania kom-
pilatora, aby siÚ nie przejmowaï, zaïoĝyï, ĝe wszystko jest w najlepszym porzÈdku,
i potraktowaï napotkane wyraĝenie tak, jakby miaïo ten szczególny typ danych. Wyko-
rzystanie dowolnego interfejsu programistycznego, który uĝywa typu object do przeka-
zywania parametrów wejĂciowych lub zwracania wyniku, prÚdzej czy póěniej bÚdzie
1 PrawdÚ mówiÈc, jest to „historia na potrzeby wprowadzenia do rozdziaïu” — niekoniecznie caïkowicie
prawdziwa.
3.1.
Czemu potrzebne sÈ typy generyczne?
93
wymagaÊ rzutowania. Pewnym uïatwieniem jest wprowadzenie hierarchii klas bazujÈcej
na typie object. Podstawowy problem pozostanie ten sam — typ object jest zupeïnie
prosty, a wiÚc ĝeby móc wykonaÊ jakÈkolwiek uĝytecznÈ pracÚ, trzeba w pierwszej
kolejnoĂci dokonaÊ jego rzutowania.
Czy rzutowanie nie jest „be”? Nie, nie naleĝy rozumieÊ, ĝe nigdy nie powinno siÚ
tego robiÊ (rzutowanie przydaje siÚ do pracy ze strukturami mutowalnymi i publicz-
nymi polami klas), ale trzeba je traktowaÊ jako zïo konieczne. Rzutowanie wskazuje,
ĝe jesteĂ zmuszony do przekazania kompilatorowi dodatkowej wiedzy i wskazania, aby
ten zaufaï Ci w czasie kompilacji i przeniósï sprawdzenie poprawnoĂci zaïoĝeñ do czasu
wykonania.
JeĂli musisz daÊ do zrozumienia, ĝe masz wiÚcej wiedzy niĝ kompilator i dlatego
chcesz dokonaÊ rzutowania, takiej samej wiedzy bÚdzie potrzebowaÊ osoba czytajÈca
Twój kod. Moĝesz pozostawiÊ komentarz w miejscu rzutowania, ale nie bÚdzie to szcze-
gólnie uĝyteczne. Znacznie lepszym miejscem na takÈ informacjÚ jest deklaracja metody
lub zmiennej. Jest to szczególnie waĝne, jeĂli dostarczasz typ lub metodÚ, z której inni
uĝytkownicy bÚdÈ korzystaÊ bez dostÚpu do Twojego kodu. Typy generyczne umoĝli-
wiajÈ dostawcom bibliotek zablokowanie wywoïañ z wnÚtrza bibliotek z uĝyciem nie-
prawidïowych parametrów. W C# 1 musieliĂmy polegaÊ na rÚcznie napisanej doku-
mentacji, która (jak kaĝda zduplikowana informacja) szybko staje siÚ niekompletna
i nieaktualna. Kiedy moĝemy takÈ informacjÚ zawrzeÊ bezpoĂrednio w kodzie jako
czÚĂÊ deklaracji metody lub typu, praca wszystkich stron staje siÚ bardziej produk-
tywna. Kompilator moĝe dokonaÊ wiÚcej sprawdzeñ, Ărodowisko IDE moĝe zaoferowaÊ
dodatkowe informacje poprzez mechanizm IntelliSense (na przykïad podczas prze-
glÈdania elementów listy ïañcuchów moĝe pokazaÊ pola i metody typu string), uĝyt-
kownicy metod bÚdÈ pewniejsi co do poprawnoĂci swojego kodu pod wzglÚdem prze-
kazanych argumentów i zwróconych wartoĂci, a czytelnicy Twojego kodu bÚdÈ mogli
lepiej zrozumieÊ, co miaïeĂ na myĂli, kiedy pisaïeĂ dany fragment.
CZY TYPY GENERYCZNE ZREDUKUJk LICZB} TWOICH B}DÓW?
Wszystkie opisy typów generycznych, jakie czytaïem (wïÈczajÈc w to moje wïasne),
podkreĂlajÈ znaczenie przeniesienia sprawdzenia poprawnoĂci typów z czasu
wykonania na czas kompilacji. PowierzÚ Ci maïy sekret: nie przypominam sobie,
abym kiedykolwiek musiaï poprawiaÊ bïÈd w wypuszczonym kodzie spowodowany
brakiem sprawdzenia typu. Inaczej mówiÈc, rzutowania, które umieszczaliĂmy
w C# 1, zawsze dziaïaïy. Umieszczenie rzutowania w kodzie dziaïa trochÚ jak
znak ostrzegawczy, dziÚki czemu zwracamy wiÚkszÈ uwagÚ na poprawnoĂÊ typów.
Typy generyczne byÊ moĝe nie zmniejszÈ radykalnie bïÚdów zwiÈzanych z bez-
pieczeñstwem typów, ale wprowadzona przez nie czytelnoĂÊ kodu wpïynie
pozytywnie na redukcjÚ bïÚdów zwiÈzanych z uĝyciem kodu przez jego odbiorców.
Prosty kod ma wiÚkszÈ szansÚ byÊ dobrze zrozumiany. O wiele ïatwiej jest
napisaÊ dobry kod, który musi byÊ odporny na nieprzemyĂlane zachowania pro-
gramistów, kiedy odpowiednie gwarancje co do typu argumentów zapewnia sam
system typów.
To, co do tej pory powiedzieliĂmy o typach generycznych, przemawia wystarczajÈco
na ich korzyĂÊ, ale sÈ teĝ jeszcze korzyĂci pod wzglÚdem wydajnoĂciowym. Po pierw-
sze, skoro kompilator moĝe wykonaÊ wiÚcej sprawdzeñ na etapie kompilacji, pozostaje
94
ROZDZIAà 3
Parametryzowanie typów i metod
mniej rzeczy do weryfikacji w czasie wykonania. Po drugie, kompilator JIT moĝe trak-
towaÊ typy wartoĂciowe w sprytniejszy sposób, dziÚki czemu w wielu sytuacjach udaje
siÚ uniknÈÊ opakowywania i odpakowywania wartoĂci. W pewnych przypadkach moĝe
to zdecydowanie wpïynÈÊ zarówno na wydajnoĂÊ, jak i zuĝycie pamiÚci.
Wiele z korzyĂci, jakie dajÈ typy generyczne, moĝe do zïudzenia przypominaÊ te
pïynÈce z przewagi statycznego systemu typów nad systemem dynamicznym. Mowa tu
o lepszej weryfikacji typów na poziomie kompilacji, wiÚkszej liczbie informacji zawar-
tych bezpoĂrednio w kodzie, lepszym wsparciu ze strony Ărodowiska IDE i lepszej
wydajnoĂci. Powód jest prosty: kiedy korzystasz z ogólnego interfejsu programistycz-
nego (na przykïad z klasy ArrayList), który nie jest w stanie wykryÊ róĝnic pomiÚdzy
róĝnymi typami, znajdujesz siÚ — jeĂli chodzi o dostÚp do tego interfejsu — w sytuacji
dynamicznego systemu typów. Warto przy okazji wspomnieÊ, ĝe sytuacja odwrotna —
przewaga dynamicznego systemu typów nad systemem statycznym — ma miejsce w nie-
licznych przypadkach (korzyĂci pïynÈce z zastosowania dynamicznych jÚzyków rzadko
sÈ bowiem zwiÈzane z koniecznoĂciÈ dokonania wyboru pomiÚdzy interfejsem gene-
rycznym i niegenerycznym). Kiedy moĝesz skorzystaÊ z typów generycznych, decyzja
o ich uĝyciu jest oczywista.
To wszystko czeka na nas w C# 2 — teraz przyszïa pora na rzeczywiste wykorzy-
stanie typów generycznych.
3.2. Proste typy generyczne do codziennego uĪycia
Jeĝeli chcesz wiedzieÊ wszystko o typach generycznych, musisz mieÊ ĂwiadomoĂÊ, ĝe
majÈ one wiele skomplikowanych elementów. Specyfikacja jÚzyka C# przedstawia
caïy szereg szczegóïowych informacji, aby opisaÊ zachowanie w niemal kaĝdej moĝliwej
sytuacji. My nie musimy jednak znaÊ wszystkich przypadków szczególnych, aby wyko-
rzystaÊ typy generyczne w sposób produktywny. (W rzeczywistoĂci ta sama zasada
obowiÈzuje dla dowolnego obszaru jÚzyka. Dla przykïadu nie musisz znaÊ wszystkich
zasad rzÈdzÈcych przypisaniami, wystarczy, ĝe bÚdziesz umiaï naprawiÊ kod w przypadku
bïÚdu kompilacji).
W tym podrozdziale opiszemy wszystko, co powinieneĂ wiedzieÊ o typach gene-
rycznych, aby móc zastosowaÊ je w codziennej pracy — zarówno w sensie uĝytkownika
interfejsu stworzonego przez innych programistów, jak i producenta wïasnych inter-
fejsów. Jeĝeli utkniesz na tym etapie, proponujÚ, abyĂ siÚ skoncentrowaï na wiedzy
potrzebnej do korzystania z typów i metod generycznych zawartych w Ărodowisku
i innych bibliotekach. Ta wiedza jest przydatna o wiele czÚĂciej niĝ umiejÚtnoĂÊ samo-
dzielnego tworzenia typów i metod generycznych.
Zaczniemy od przyjrzenia siÚ jednej z klas kolekcji wprowadzonych w .NET 2.0 —
Dictionary TKey, TValue .
3.2.1. Nauka przez przykáad — sáownik typu generycznego
Uĝycie typów generycznych jest proste, o ile nie napotkasz przypadkiem jakiegoĂ
ograniczenia i nie zaczniesz siÚ zastanawiaÊ, czemu Twoje rozwiÈzanie nie chce dziaïaÊ.
Bez jakiejkolwiek wiedzy teoretycznej moĝesz z ïatwoĂciÈ przewidzieÊ zachowanie
3.2.
Proste typy generyczne do codziennego uĝycia
95
kodu, po prostu go analizujÈc. KorzystajÈc z metody prób i bïÚdów, bÚdziesz w stanie
napisaÊ wïasny dziaïajÈcy kod. (Jednym z udogodnieñ typów generycznych jest to, ĝe
spora czÚĂÊ weryfikacji kodu odbywa siÚ w czasie kompilacji, jest zatem spora szansa,
ĝe Twój kod bÚdzie dziaïaï, kiedy doprowadzisz do pomyĂlnej kompilacji — takie zacho-
wanie jeszcze bardziej upraszcza eksperymentowanie z kodem). OczywiĂcie, celem
tego rozdziaïu jest wyposaĝenie CiÚ w wiedzÚ, dziÚki której nie bÚdziesz musiaï zga-
dywaÊ — bÚdziesz dokïadnie wiedziaï, co siÚ dzieje na kaĝdym kroku.
Teraz przyjrzyjmy siÚ fragmentowi kodu, który wyglÈda w miarÚ prosto, nawet jeĂli
skïadnia jest nieznajoma. Listing 3.1 uĝywa typu Dictionary TKey, TValue (w przy-
bliĝeniu generycznego odpowiednika niegenerycznej klasy Hashtable) do zliczenia czÚ-
stotliwoĂci wystÚpowania sïów w zadanym tekĂcie.
Listing 3.1. UĪycie Dictionary TKey, TValue do zliczenia sáów w tekĞcie
static Dictionary string, int CountWords(string text)
{
Dictionary string, int frequencies;
frequencies = new Dictionary string, int ();
string[] words = Regex.Split(text, @ W+ );
Utworzenie nowego sáownika
„sáowo – liczba wystąpieĔ”
Utworzenie
nowego sáownika
„sáowo – liczba
wystąpieĔ”
foreach (string word in words)
{
if (frequencies.ContainsKey(word))
{
frequencies[word]++;
}
else
{
frequencies[word] = 1;
}
}
return frequencies;
}
...
string text = @ Chodzi lisek kođo drogi,
Cichuteēko stawia nogi,
Cichuteēko siú zakrada,
Nic nikomu nie powiada. ;
Dodanie do sáownika
lub jego uaktualnienie
Dictionary string, int frequencies = CountWords(text);
foreach (KeyValuePair string, int entry in frequencies)
{
string word = entry.Key;
int frequency = entry.Value;
Console.WriteLine( {0}: {1} , word, frequency);
}
Utworzenie
komórki
widoku tabeli
Metoda CountWords tworzy pusty sïownik dla par ïañcuch (string) – liczba (int) (
).
Jej zadaniem bÚdzie zliczanie wystÈpieñ kaĝdego sïowa w zadanym tekĂcie. NastÚpnie
) do podzielenia tekstu na sïowa. Wyraĝenie nie jest
uĝywamy wyraĝenia regularnego (
szczególnie wyszukane — ze wzglÚdu na kropkÚ na koñcu zdania wĂród sïów pojawia
siÚ pusty ïañcuch, a te same sïowa pisane wielkÈ i maïÈ literÈ sÈ traktowane jako róĝne.
96
ROZDZIAà 3
Parametryzowanie typów i metod
Problemy te moĝna ïatwo rozwiÈzaÊ — nie zrobiïem tego tylko dlatego, aby uzyskaÊ
jak najprostszy kod dla tego przykïadu. Sprawdzamy, czy dane sïowo jest juĝ w naszym
sïowniku. JeĂli jest, zwiÚkszamy licznik, w przeciwnym razie tworzymy wartoĂÊ poczÈt-
). ZwróÊ uwagÚ, ĝe kod dokonujÈcy inkrementacji nie musi wykony-
kowÈ licznika (
waÊ rzutowania na typ int. Wiemy, ĝe otrzymana wartoĂÊ jest typu int juĝ na etapie
kompilacji. Krok wykonujÈcy inkrementacjÚ tak naprawdÚ pobiera indekser sïownika,
zwiÚksza wartoĂÊ, a nastÚpnie ustawia indekser z powrotem. Niektórzy programiĂci wolÈ
wykonaÊ ten krok w sposób jawny, uĝywajÈc wyraĝenia frequencies[word] = frequen
´cies[word] + 1;.
Ostatnia czÚĂÊ listingu wyglÈda znajomo: enumeracja przez instancjÚ typu Hashtable
daje podobnÈ (niegenerycznÈ) parÚ DictionaryEntry z wïaĂciwoĂciami Key i Value dla
). Róĝnica polega na tym, ĝe w C# 1 klucz i wartoĂÊ zosta-
kaĝdego elementu kolekcji (
ïyby zwr
Pobierz darmowy fragment (pdf)