Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Programowanie zaawansowane Zaawansowane konstrukcje języka C#

Podobne prezentacje


Prezentacja na temat: "Programowanie zaawansowane Zaawansowane konstrukcje języka C#"— Zapis prezentacji:

1 Programowanie zaawansowane Zaawansowane konstrukcje języka C#

2 Plan wykładu Niejawne typowanie zmiennych lokalnych
Właściwości automatyczne Metody rozszerzeniowe Metody częściowe Inicjalizator obiektów Typy anonimowe

3 Niejawne typowanie zmiennych lokalnych

4 Jawne deklarowanie zmiennych
Dotychczasowe doświadczenia z językiem C# pokazują, że zmienne (np. w ciele metody) deklarowane są w jawny sposób – jawnie podajemy typ deklarowanej zmiennej.

5 Niejawne typowanie zmiennych lokalnych
C# udostępnia słowo kluczowe var, które możemy użyć zamiast jawnego podania typu zmiennej. W przypadku użycia tego słowa, kompilator wywnioskuje typ zmiennej na podstawie początkowej wartości nadanej tej zmiennej w momencie jej inicjalizacji.

6 Czy var to słowo kluczowe?
Ściśle mówiąc, var nie jest słowem kluczowym języka C#. Dopuszczalne jest deklarowanie zmiennych, parametrów, pól danych o takiej nazwie bez pojawienia się jakichkolwiek ostrzeżeń w czasie kompilacji. Jednakże, gdy słowo var wystąpi jako typ zmiennej, na podstawie kontekstu traktowane jest jako słowo kluczowe.

7 Niejawne typowanie Niejawne typowanie możemy stosować w przypadku deklarowania dowolnego typu, w tym: tablic, typów generycznych, naszych własnych typów niestandardowych.

8 Niejawnie typowanie w pętli foreach
Słowa kluczowego var można również używać w standardowej pętli foreach. Kompilator sam poprawnie wywnioskuje typ zmiennej, za pomocą której przechodzimy po elementach wskazanej kolekcji. W poniższym przykładzie, iterujemy po elementach niejawnie zadeklarowanej tablicy liczb całkowitych.

9 Niejawnie typowanie w pętli foreach c. d.
Gwoli wyjaśnienia, w pętli foreach możemy użyć jawnie zadeklarowanego iteratora do przechodzenia po elementach niejawnie zadeklarowanej tablicy.

10 Ograniczenia niejawnego typowania
Niejawnego typowania możemy używać tylko w przypadku deklarowania zmiennych lokalnych w ramach ciała metody lub właściwości. Nielegalnym jest używanie słowa kluczowego var do deklarowania typu zwracanego przez metodę, typów parametrów metod oraz typów pól danych klas lub struktur.

11 Ograniczenia niejawnego typowania c. d.
Do zmiennych lokalnych deklarowanych przy użyciu słowa var musi być przypisana wartość początkowa w momencie deklaracji. Dodatkowo, wartością tą nie może być null. Wynika to z oczywistego faktu: kompilator musi mieć podstawę do wywnioskowania typu deklarowanej zmiennej.

12 Ograniczenia niejawnego typowania c. d. 2
Do już zainicjalizowanej zmiennej możemy przypisać wartość null, Zmienną niejawnie zadeklarowaną możemy przypisać do innej zmiennej (zadeklarowanej jawnie lub niejawnie), Możemy zwrócić zmienną zadeklarowaną niejawnie, o ile typ wartości zwracanej przez daną metodą jest zgodny z typem zwracanej zmiennej.

13 Ograniczenia niejawnego typowania c. d. 3
Nie można również deklarować nulowalnych, niejawnie typowanych zmiennych lokalnych. Deklarowanie niejawnie typowanych zmiennych jako nulowanych nie ma sensu, ponieważ nie można do nich przypisać wartości null w momencie inicjalizacji.

14 Niejawnie typowane lokalne tablice
Stosując technikę niejawnego typowania możemy zadeklarować tablicę nie podając typu jej elementów.

15 Niejawnie typowane lokalne tablice c. d.
Tak, jak w przypadku jawnego deklarowania tablicy, lista inicjalizacyjna musi zawierać elementy tego samego typu (same liczby, same napisy). W przypadku niejawnego deklarowania lokalnej tablicy o różnych elementach, wywnioskowanym typem nigdy nie stanie się klasa bazowa System.Object. Poniższa deklaracja spowoduje błąd kompilacji.

16 Niejawne typowanie a silne typowanie
Niejawnie typowane dane są silnie typowanymi danymi. Technika niejawnego typowania realizowana jest w momencie deklaracji zmiennej i polega na niejawnym wywnioskowaniu i nadaniu typu deklarowanej zmiennej. Później dana zmienna jest traktowana jak każda inna.

17 Zastosowanie niejawnego typowania
Samo niejawne deklarowanie lokalnych zmiennych, których typy doskonale znamy nie ma większego sensu. Takie postępowanie prowadziłoby do zmniejszenia czytelności kodu. Główne zastosowania tej techniki (jak i wielu innych) ma miejsce w technologii LINQ. Technologia ta pozwala na korzystanie z zapytań (ang. query expression), których rezultatem są dynamicznie tworzone zbiory wyników powstałe na podstawie samego formatu zapytania. Stosując niejawne deklarowanie zmiennych, nie musimy znać typu zwracanego przez te wyrażenia, co, dodatkowo, nie w każdym przypadku jest w ogóle możliwe (np. gdy używany typów anonimowych).

18 Zastosowanie niejawnego typowania c. d.

19 Automatyczne właściwości

20 Właściwości C# preferuje stosowanie właściwości w celu zapewnienia bezpieczeństwa dostępu i przypisywania nowych wartości prywatnym polom danych (w odróżnieniu od tradycyjnie używanych metod GetXXX() i SetXXX()).

21 Właściwości automatyczne
Chociaż definiowanie takich właściwości nie stanowi intelektualnej zagadki stulecia (szczególnie stosująć propfull + tab tab), zdefiniowanie ich, na przykład, dla 15 pól danych wiąże się ze sporym nakładem czasowym. Ma to szczególne zastosowanie w przypadku, gdy definiowane właściwości tylko zwracają i przypisują wartość polom prywatnym. W celu uproszczenia procesu hermetyzacji danych , C# wprowadza automatyczne właściwości. Mechanizm ten zastępuje definiowanie prywatnej zmiennej i tworzenie ciała odpowiedniej właściwości.

22 Właściwości automatyczne c. d.
Podczas definiowania właściwości podajemy modyfikator dostępu, typ danych, nazwę właściwości oraz pusty blok get/set. W czasie kompilacji, do danego typu zostanie dodane odpowiednie, prywatne pole danych oraz odpowiednia implementacja logiki bloku get/set. W przypadku, gdy chcemy w metodach get i set umieścić dodatkową funkcjonalność (walidacja itd.) musimy zdefiniować tradycyjną właściwość. Gotowiec o nazwie „prop” (ang. code snippet) w środowisku Visual Studio 2013 został zastąpiony wersją obsługującą automatyczne właściwości (wcześniej obsługiwał tradycyjne właściwości).

23 Ograniczenie automatycznych właściwości
W odróżnieniu od tradycyjnych, właściwości automatyczne muszą posiadać zarówno implementację metody get i metody set. Oznacza to, że nie można za ich pomocą definiować właściwości tylko do odczytu lub tylko do zapisu pomijając jeden z bloków..

24 Odwołaniado automatycznych właściwości
Programista nie ma bezpośredniego dostępu do wygenerowanego prywatnego pola danych, nawet z wnętrza typu, w którym zostało wygenerowane. Dostęp z zewnątrz do właściwości wygląda dokładnie tak samo, jak w przypadku tradycyjnych właściwości.

25 Ograniczanie dostępu W przypadku tradycyjnych właściwości możemy definiować modyfikatory dostępu osobno dla metody get i set. Tak samo możemy postąpić w przypadku właściwości automatycznych (ograniczając w ten sposób dostęp do wybranej metody z zewnątrz typu).

26 Metody rozszerzeniowe

27 Metody rozszerzeniowe
Gdy typ jest zdefiniowany i skompilowany do pakietu platformy .NET, nie możemy zmieniać sposobu, w jaki został zdefiniowany. Jedynym sposobem na dodanie nowych składowych, aktualizowanie składowych lub ich usunięcie jest modyfikacja i ponowna kompilacja kodu. W C# możliwe jest definiowanie metod rozszerzeniowych (rozszerzających). Metody rozszerzeniowe pozwalają na dodanie nowej funkcjonalności do istniejących, skompilowanych typów (klas, struktur i interfejsów) lub typów aktualnie kompilowanych, bez konieczności bezpośredniej ich zmiany.

28 Wszystko jest iluzją Technika ta jest bardzo użyteczna, gdy chcemy wstrzyknąć nową funkcjonalność do typu, dla którego nie posiadamy kodu bazowego. Możemy jej również użyć do „zmuszenia” typu do dostarczania zbioru składowych (które mogą zostać użyte w mechanizmie polimorfizmu), ale nie możemy zmodyfikować oryginalnej deklaracji typu. Używając metod rozszerzeniowych możemy dodać funkcjonalność do prekompilowanych typów, jednocześnie tworząc iluzje obecności tych metod w oryginalnych deklaracjach typów.

29 Ograniczenia metod rozszerzeniowych
Metody rozszerzeniowe muszą być definiowane w statycznych klasach. Dlatego też, każda metoda rozszerzeniowa musi być zadeklarowana jako statyczna. Metody są oznaczane jako rozszerzające poprzez użycie słowa kluczowego this jako modyfikatora pierwszego (i tylko pierwszego) parametru danej metody. Każda metoda rozszerzeniowa może być wywołana z aktualnej instancji typu lub statycznie, poprzez definiującą ją klasę statyczną.

30 Definiowanie metod rozszerzeniowych
Załóżmy, że chcemy zdefiniować klasę narzędziową zawierającą dwie metody rozszerzeniowe. Pierwsza z nich rozszerzy klasę System.Object o całkowicie nową metodę pozwalającą na wyświetlenie informacji o pakiecie, w którym dany typ został zdefiniowany. Druga metoda rozszerzy typ System.Int32 o możliwość odwracania kolejności cyfr w liczbie.

31 Definiowanie metod rozszerzeniowych c. d.

32 Definiowanie metod rozszerzeniowych c. d. 2
Przed definicją typu pierwszego parametru każdej z metod rozszerzeniowych znajduje się słowo kluczowe this. Pierwszy parametr metody rozszerzeniowej wskazuje na typ, który dana metoda rozszerza. Ponieważ metoda DisplayDefiningAssembly() rozszerza klasę System.Object, każdy typ w każdym z pakietów posiada teraz taką metodę. Metoda ReverseDigits() rozszerza tylko typ int. Próba wywołania jej dla innych typów spowoduje błąd kompilatora.

33 Definiowanie metod rozszerzeniowych c. d. 3
Metoda rozszerzająca może przyjmować dowolną liczbę parametrów. Jednak tylko pierwszy parametr może być poprzedzony słowem kluczowym this (wskazywać na typ rozszerzany przez daną metodę).

34 Wywołanie metod rozszerzeniowych

35 Wywołanie metod rozszerzeniowych c. d.
Na poprzednim slajdzie pokazano przykłady wywołania metod rozszerzających z poziomu instancji rozszerzanych typów. „W tle” kompilator wywołuje odpowiednie metody statyczne, przekazując dany obiekt jako pierwszy parametr danej metody (ten oznaczony słowem kluczowym this w jej definicji). Nic nie stoi na przeszkodzie tego, żebyśmy sami mogli wywołać jawnie odpowiednie metody statyczne z naszych klas narzędziowych (co pokazano na następnym slajdzie).

36 Wywołanie metod rozszerzeniowych c. d. 2

37 Dostęp do rozszerzanego typu
Metody rozszerzeniowe są statycznymi metodami, które można wywołać na poziomie instancji rozszerzanego typu. W odróżnieniu od „zwykłych„ metod nie mają one bezpośredniego dostępu do składowych rozszerzanego typu. Mówiąc inaczej, metody takie działają na obiektach danej klasy, a nie są jej składową. Rozważmy następujący przykład. Mamy prosty typ Car.

38 Dostęp do rozszerzanego typu c. d.
Chcąc napisać metodę rozszerzającą ten typ (zmniejszającą prędkość) nie możemy tego zrobić w poniższy sposób. Do składowych publicznych rozszerzanej klasy musimy odwoływać się poprzez pierwszy parametr metody rozszerzającej.

39 Dostęp do rozszerzanego typu c. d. 2
Biorąc pod uwagę sposób, w jaki są realizowane metody rozszerzające, brak bezpośredniego dostępu do składowych rozszerzanego typu jest oczywisty. Tworzymy zewnętrzną metodę operującą na instancji danej klasy. Z drugiej jednak strony, sam sposób wywołania metody rozszerzającej z poziomu instancji wskazywałaby na istnienie takiej możliwości.

40 Widoczność metod rozszerzających
Statyczne klasy z metodami rozszerzającymi definiowane są przez nas w pewnej przestrzeni nazw. Podobnie jak z typami, aby móc z nich skorzystać w innych projektach (innych przestrzeniach nazw) musimy je wskazać poprzez użycie słowa kluczowego using. Jeżeli tego nie zrobimy, obiekty w danej przestrzeni nie będą posiadać dodatkowych (zdefiniowanych przez nas w innym zakresie widoczności) metod rozszerzających.

41 System pomocy Biorąc pod uwagę fakt, że metody rozszerzające nie są definiowane dosłownie w rozszerzanym typie, korzystanie z nich podczas kodowania może być niewygodne. Korzystając z systemu pomocy, w przypadku istnienia metod rozszerzających, po wyświetleniu listy z możliwymi metodami może się okazać, że znajduje się tam wiele metod nie istniejących w oryginalnej definicji. Na szczęście, system IntelliSense wyróżnia takie metody specjalną ikonką (strzałką skierowaną do dołu).

42 Rozszerzanie interfejsów
Możliwe jest również dodawanie nowej funkcjonalność do interfejsów poprzez definiowanie metod rozszerzeniowych. Powiedzmy, że mamy następującą definicję interfejsu i klasy go implementującej.

43 Rozszerzanie interfejsów c. d.
Załóżmy, że nie mamy dostępu do oryginalnego kodu interfejsu. Dlatego też chcemy zdefiniować nową metodę rozszerzeniową. Definiując taką metodę, nie wystarczy zdefiniować jej prototyp. Musimy również dostarczyć implementację danej metody. Dlaczego?

44 Rozszerzanie interfejsów c. d. 2
Ze zdefiniowanej metody możemy korzystać, jak z każdej innej składowej danego interfejsu.

45 Metody częściowe

46 Metody częściowe Od wersji .Net 2.0 mamy możliwość definiowania częściowych typów, pozwalające na rozłożenie pełnej implementacji typu na kilka plików. Dopóki wszystkie części klasy są w ten sam sposób nazywane (nazwa kwalifikowana), wynikiem ich kompilacji jest pojedyncza definicja typu w tworzonym pakiecie. C# 2008 rozszerza zastosowanie słowa kluczowego partial do stosowania na poziomie metod.

47 Ograniczenia metod częściowych
Technika metod częściowych pozwala na definiowanie prototypu metody w jednym pliku, a jej implementacji w innym pliku. Metody częściowe mają wiele istotnych ograniczeń: Mogą być definiowane tylko w klasach częściowych, Musza zwracać void, Mogą być statyczne lub instancyjne, Mogą posiadać parametry (również z atrybutami this, ref lub params, ale nie z atrybutem out), Są zawsze niejawnie prywatne.

48 Definiowanie metod częściowych
Przykładowa definicja klasy zawierająca deklarację i wywołanie metody częściowej.

49 Definiowanie metod częściowych c. d.
Jeżeli programista nie dostarczy implementacji metody zadeklarowanej jako częściowa, w czasie kompilacji „ślad po niej zaginie” – skompilowany typ nie będzie zawierał ani deklaracji takiej metody ani jej wywołań.

50 Definiowanie metod częściowych c. d. 2
Aby wywołania metody zostały włączone do typu, należy zapewnić jej implementację w osobnym pliku stanowiącym dalszą część definicji danej klasy.

51 Zastosowanie metod częściowych
Ze wszystkich nowości C# 2008, metody częściowe będą zapewne najmniej wykorzystywane ze względu na ich ograniczenia (przede wszystkim są zawsze prywatne i muszą zwracać void). Najczęstszym zastosowaniem tej techniki jest tzw. lekka obsługa zdarzeń Programista, poprzez definiowanie metody częściowej, zapewnia uchwyt do obsługi pewnych zdarzeń. Programiści korzystający z danego typu mogą zapewnić odpowiednią obsługę zdarzenia implementując metodę częściową.

52 Inicjalizator obiektów

53 Inicjalizator obiektów
C# 2008 oferuje nowy sposób nadawania początkowych wartości polom klasy poprzez tak zwaną składnię inicjalizatora obiektów. Korzystając z tej techniki możliwe jest stworzenie nowej zmiennej danego typu i przypisanie wartości jej właściwościom i publicznym polom w kilku liniach kodu. Syntaktycznie, inicjalizator obiektów składa się z listy wartości oddzielonych przecinkiem, zamkniętych w nawiasach klamrowych. Każda składowa w liście inicjalizacyjnej reprezentuje odpowiednie publiczne pole lub właściwość inicjalizowanego typu.

54 Kod przykładowej klasy

55 Użycie inicjalizatora
Dzięki inicjalizatorowi obiektów mamy kolejny sposób na utworzenie obiektu danego typu.

56 Użycie inicjalizatora c. d.
Za pomocą składni inicjalizatora można nadawać wartości właściwościom i polom publicznym typu. Jakie wartości mają pola xPos i yPos po następującym zainicjalizowaniu obiektu? Powyższy zapis odpowiada następującemu:

57 Jawne wywołanie konstruktorów
Inicjalizator może być również wywoływany po jawnym wskazaniu konstruktora. Wywołanym konstruktorem nie musi być wyłącznie konstruktor domyślny (nie posiadający żadnych argumentów).

58 Inicjowanie kolekcji Za pomocą składni inicjalizatora możemy również inicjować kolekcje.

59 Przydatność inicjalizatora
Użyteczność składni inicjaliztora obiektów można łatwo zauważyć przy inicjalizowaniu bardziej złożonych obiektów.

60 Typy anonimowe

61 Typy anonimowe Tworząc nową klasę musimy (w większości przypadków) zaimplementować następujące jej elementy przedstawione poniżej. Jeżeli chcemy stworzyć tymczasową klasę bez konieczności implementowania powyższego standardowego szkieletu możemy skorzystać z konstrukcji języka C# 2008 jakimi są typy anonimowe.

62 Definiowanie typu anonimowego
Typ anonimowy tworzymy używając słowa var, słowa kluczowego new i podając listę właściwości i ich wartości w nawiasach klamrowych.

63 Wewnętrzna reprezentacja typu anonimowego

64 Cechy typu anonimowego
Nie kontrolujemy nazwy typu, Typy anonimowe zawsze dziedziczą po System.Object. Właściwości tylko do odczytu Typy anonimowe nie wspierają metod, zdarzeń. Typy anonimowe są zawsze niejawnie zamknięte. Typy anonimowe są zawsze tworzone za pomocą domyślnego konstruktora. Przesłonięta metoda ToString() wyświetla właściwości typu w standardowy sposób. Przesłonięte metody Equals() i GetHashCode() operują na wartościach a nie na referencjach.

65 Dziękuję za uwagę

66 Pytania egzaminacyjne (Zestaw01)
Co to jest takiego ta cała platforma .NET? Jakie są jej najważniejsze cechy? Jakie elementy składają się na platformę .NET? Co to jest CLR? Co to jest CTS? Co to jest CLS? Co to jest CIL? Co to jest CLI?

67 Pytania egzaminacyjne (Zestaw02)
Co to są pakiety? Co to są typy i co do nich zaliczamy? Jaka jest zależność między pakietami, przestrzeniami nazw i typami? W jaki sposób wykonywane są programy na platformie .NET?

68 Pytania egzaminacyjne (Zestaw03)
Na czym polega OOP i jakie są jego trzy podstawowe filary? Na czym polega dziedziczenie? Do czego wykorzystujemy słowa kluczowe protected, base, sealed? Na czym polega agregacja? Na czym polega zagnieżdżanie? Na czym polega delegacja?

69 Pytania egzaminacyjne (Zestaw04)
Na czym polega polimorfizm? Co to są abstrakcyjne klasy bazowe? Co to jest interfejs polimorficzny? Na czym polega nadpisywanie i zasłanianie składowych?

70 Pytania egzaminacyjne (Zestaw05)
Czym charakteryzuje się klasa System.Object? Na czym polega obsługa wyjątków? Jakie są bloki i słowa kluczowe związane z obsługą wyjątków? Jak realizujemy przechwytywanie wielu wyjątków?

71 Pytania egzaminacyjne (Zestaw06)
Co to jest interfejs? Czym interfejs różni się od interfejsu polimorficznego? W jaki sposób implementujemy interfejsy? Do czego służą słowa kluczowe as i is? Czym się różni jawna i niejawna implementacja interfejsów? Co trzeba zrobić, aby po zawartości naszej klasy można było iterować za pomocą pętli foreach Czym się różnie płytkie i głębokie klonowanie? Co trzeba zrobić, aby kolekcję naszych obiektów można było posortować?

72 Pytania egzaminacyjne (Zestaw07)
Co to są typy generyczne? Na czym polega o/wypakowywanie i gdzie jest wykorzystywane? Wymień znane Ci kolekcje generyczne. Co to są indeksery? Na jakiej zasadzie działają metody generyczne?

73 Pytania egzaminacyjne (Zestaw08)
Co to są delegaty? Co to są zdarzenia? Co to są metody anonimowe? Co to są wyrażenia lambda? Na czym polega multicasting? Na czym polega kowariancja i kontrkowariancja? Co to są predykaty?

74 Pytania egzaminacyjne (Zestaw09)
Na czym polega niejawne typowanie typów? Co to są właściwości anonimowe? Co to są metody rozszerzeniowe? Co to są klasy i metody częściowe? W jaki sposób wykorzystujemy inicjalizator obiektów? Co to są typy anonimowe?


Pobierz ppt "Programowanie zaawansowane Zaawansowane konstrukcje języka C#"

Podobne prezentacje


Reklamy Google