obiektowka Flashcards

(98 cards)

1
Q

virtual vs abstract
metody

A

metoda:
-virtual:
+daje możliwość odwołania się do metody bazowej
+może mieć implementację w klasie pochodnej
+może mieć ciało

-abstract:
+nie daje możliwości odwołania się do metody bazowej
+musi mieć implementacji w klasie pochodnej
+nie może mieć ciała
+tylko w klasie abstrakcyjnej

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Klasa abstrakcyjna

A

Klasa abstrakcyjna nie może mieć swoich reprezentantów
pod postacią obiektów.
Klasa abstrakcyjna jest wykorzystywana wyłącznie w roli
klasy bazowej dla innych klas.
Klasa staje się abstrakcyjną, gdy zawiera choćby jedną
abstrakcyjną metodę lub właściwość.
Klasa potomna względem klasy abstrakcyjnej musi
implementować wszystkie jej abstrakcyjne metody
i właściwości.
Klasa abstrakcyjna może zawierać także pola
oraz nieabstrakcyjne metody i właściwości.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Klasa zamknięta (finalna)

A

Klasa zamknięta nie może być bazową
dla klas od niej pochodnych.
Klasy zamknięte zapobiegają
przypadkowemu dziedziczeniu.
Metody zamknięte (finalne) stosuje się wówczas,
gdy działanie metody jest sprawdzone, poprawne, stabilne
i nie wymaga dalszych zmian.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Interfejs

A

-Interfejs jest tworem abstrakcyjnym podobnym do klasy,
ale posiada on jedynie deklaracje składowych,
które od C#8 może dodatkowo implementować.

-Nie można utworzyć obiektu będącego instancją interfejsu.

-Interfejs może zawierać: zagnieżdżone typy (np. klasy),
stałe, metody, właściwości, zdarzenia, indeksery.

-Interfejs nie może zawierać pól, operatorów,
konstruktorów i destruktorów.

-Klasa może dziedziczyć tylko po jednej klasie, ale może
implementować wiele interfejsów lub dziedziczyć po nich.

-Klasa implementująca interfejs może być tak samo lub
bardziej dostępna niż interfejs.

-Interfejs rozszerzający nie może być bardziej dostępny od
któregokolwiek interfejsu bazowego.

-Interfejs może być interfejsem rozszerzającym dla wielu
innych interfejsów (gdy po nich dziedziczy).

-Interfejsy mogą być włączone w dowolne miejsce hierarchii
dziedziczenia, w przeciwieństwie do klas abstrakcyjnych.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

interfejs vs klasa abstrakcyjna

A

abstrakcja:
-nie może mieć obiektów
-wszystkie abstrakcyjne muszą być implementowane
-określone miejsce w hierarchii
-jedna klasa abstrakcyjna
-może mieć: pola, operatory, konstruktory, destruktory

interfejs:
-też nie może mieć obiektów
-wszystkie bez funkcjonalności muszą być implementowane
-dowolne miejsce w hierarchii
-wiele interfejsów
-nie może mieć: pól, operatorów, konstruktorów, destruktorów

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

SOLID

A

S — zasada pojedynczej odpowiedzialności
(SRP, ang. Single Responsibility Principle)
O — zasada otwarte-zamknięte
(OCP, ang. Open-Closed Principle)
L — zasada podstawienia Liskov
(LSP, ang. Liskov Substitution Principle)
I — zasada separacji interfejsów
(ISP, ang. Interface Segregation Principle)
D — zasada odwrócenia zależności
(DIP, ang. Dependency Inversion Principle)

Zasada pojedynczej odpowiedzialności
(SRP, ang. Single Responsibility Principle) mówi,
że każda klasa (a zatem obiekt) powinna odpowiadać
za jak najmniejszy fragment logiki programu.
Stosowanie zasady SRP redukuje odpowiedzialność
każdej z klas i zwiększa prawdopodobieństwo
ponownego ich użycia.

Zasada otwarte-zamknięte (OCP, ang. Open-Closed
Principle) mówi, że klasy, moduły, funkcje itp. powinny być
otwarte na rozszerzenia, a zamknięte na modyfikacje.
Zgodnie z zasadą OCP powinna istnieć możliwość
uzyskania nowych funkcjonalności
poprzez rozszerzenie elementu
(np. przez dziedziczenie
lub tworzenie statycznych metod rozszerzających),
a nie zmianę już istniejącego.

Zasada podstawienia Liskov mówi, że: „funkcje, które
używają wskaźników lub referencji do klas bazowych,
muszą być w stanie używać również obiektów klas
dziedziczących po klasach bazowych, bez dokładnej
znajomości tych obiektów”…
…co w praktyce oznacza przede wszystkim to, że
klasa dziedzicząca po klasie bazowej nie powinna zmieniać
jej funkcjonalności, tylko rozszerzać możliwości.

Zasada separacji interfejsów (ISP, ang. Interface
Segregation Principle) mówi, że tworzone interfejsy muszą
być odpowiedzialne za jak najmniejszą funkcjonalność.
Wynika to z faktu, że nadmienienie rozbudowany interfejs
(zwany tłustym lub zanieczyszczonym) wymaga
implementacji w klasach potomnych metod,
które być może nie będą nigdy wykorzystane.

Zasada odwrócenia zależności (DIP, ang. Dependency
Inversion Principle) mówi, że kod warstw wyższego poziomu
(np. klas potomnych) nie powinien zależeć od kodu niższych
warstw (np. klas bazowych).
Zgodnie z DIP obie warstwy powinny być od siebie
niezależne, ale zależeć od pewnych abstrakcji.
Jednocześnie abstrakcje nie powinny zależeć od
szczegółów.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Kolejność wykonywania konstruktorów

A

1) statyczne i klas bazowych w kolejności dziedziczenia
2) konstruktory obiektowych pól klasy
3) konstruktory klasy

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Metoda statyczna
Z czym związana?

A

jest zatem związana z typem
(nie instancją, czyli obiektem).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Klasa statyczna
Kiedy się stosuje?
Różnice między niestatyczną
Dziedziczenie

A

Klasy statyczne stosuje się, gdy nie ma potrzeby korzystania
z indywidualnego stanu klasy.

Klasa statyczna może zawierać metody i pola statyczne.
Klasa niestatyczna może zawierać metody i pola statyczne
oraz niestatyczne

Klasa statyczna nie może implementować interfejsów
i brać udziału w dziedziczeniu.

Do klas statycznych nie odnosi się this, base (dziedziczenie).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Konstruktor statyczny
kiedy używany?

A

jest używany wówczas, gdy należy
zainicjalizować statyczną składową niestatycznej klasy bez
konieczności tworzenia instancji klasy.

Konstruktor statyczny uruchamiany jest w chwili tworzenia
pierwszego obiektu niestatycznej klasy tylko 1. raz, po nim
uruchamiane są (wielokrotnie) konstruktory niestatyczne.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Operator konwersji niejawnej (np. double poleFigury = prostokąt1; )
Operator konwersji jawnej (np. double poleFigury = (double)prostokąt1; )
Operator jednoargumentowy (np. Liczba liczbaOdwrotna=-liczba; )
Operator dwuargumentowy (np. Liczba liczba=liczba1+liczba2; )

A

public static implicit operator typwyjściowy(typwejściowy arg1)

public static explicit operator typwyjściowy(typwejściowy arg1)

public static typwyniku operator typoperatora1arg(typargu1 arg1)

public static typwyniku operator typoperatora2arg(typargu1 arg1 ,typargu2 arg2)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Przeciążając operatory == i !=, należy również
i co robią?

A

nadpisać
metody Equals() i GetHashCode(), które są dziedziczone po
klasie System.Object. W przeciwnym przypadku kompilator
zgłosi ostrzeżenie.

TRZEBA JE PRZECIĄŻĄĆ PARAMI

Metoda Equals() działa jak operator == i sprawdza,
czy porównywane obiekty są równe.
dla typów referencyjnych porównuje referencje

Metoda GetHashCode()
zwraca swego rodzaju
identyfikator obiektu. Jest
on zawsze równy dla tych
samych reprezentacji
w pamięci, ale nie musi
być różny dla różnych
obiektów (powtarza się co
ok. 10 tyś. obiektów)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

GUID
co to? rozmiar? jak użyć?

A

Zmienne GUID (globally unique identifier) są 128b (16B)
liczbami całkowitymi, które mogą być używane tam, gdzie
wymagane są niepowtarzalne identyfikatory (m.in.
w b.d., w których klucz główny musi być unikatowy, np. w
przypadku, gdy ocena może być dodana do dowolnego
zasobu aplikacji, więc jej identyfikator musi być unikatowy).

Guid Guid1 = Guid.NewGuid();

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

aby przeciążyć operatory true false

A

należy również przeciążyć operatory które zwracają te wartości

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Indeksator jest
Indeksatory pozwalają
Indeksator musi zawierać
Indeksatory mogą być przekazywane jako argumenty metod
Dlaczego nie może być statyczny?

A

kolekcją podobną do tablicy
ale indeksy mogą być innych typów
niestatyczny
Nie można tworzyć statycznych indeksatorów,
ponieważ indeksatory są powiązane z obiektami.

wygodnie odwoływać się do tablicy
lub innej struktury danych zadeklarowanej w klasie.

co najmniej jedną deklarację
dostępu get lub set (podobnie jak właściwość).
Składnia indeksatora jest analogiczna do właściwości.
[modyfikatory] typ this[argumenty_indeksów]{
deklaracje_dostępu //skojarzenie wartości z indeksami
}

tylko przez wartość. Nie mogą być więc one przekazywane
przez referencję (ref) i wyjście (out).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Struktury
jaki typ?
kiedy stosować?
dziedziczenie czy mogą, co z interfejsem
przypisywanie wartości i struktur
co mogą zawierać?
modyfikator readonly
jak działa new?

A

Struktury są mniej rozbudowaną alternatywą dla klas.

Struktury są typem wartości (bezpośrednim), nie zaś typem
referencyjnym, zatem niejawnie dziedziczą po klasie
bazowej „System.ValueType” (choć ta dziedziczy po Object).

Struktury należy wykorzystywać dla prostych, niewielkich
(do 16 bajtów) i krótkotrwałych danych, które są tworzone na
stosie. Gwarantuje to wówczas wydajność większą
niż w przypadku stosowania obiektów klas.

Struktury nie obsługują dziedziczenia,
ale mogą implementować interfejsy.

Podczas przypisania zmiennych typu struktura wartości
są kopiowane - powstają dwie odrębne kopie
tych samych danych.

Struktury są podobne do klas: mogą zawierać stałe, pola,
metody, właściwości, indeksatory, zdarzenia, konstruktory,
przeciążone operatory.

Struktury nie mogą zawierać bezpośredniej inicjalizacji pól
typu: int i=10;.

W strukturze od C#10 można definiować konstruktor
bezparametrowy (tak jak każdy), ale musi inicjować wszystkie parametry
struktury. Nie można natomiast tworzyć finalizerów.

Modyfikator readonly stosuje się do tych składowych struktur
(np. metod), które nie modyfikują ich stanu.

Słowo new nie oznacza działań typowych dla klas i
obiektów: nie tworzy nowego obiektu na stercie, ale oznacza
wywołanie konstruktora bezparametrowego w celu
inicjalizacji wszystkich pól struktury
(kompletnego stanu struktury)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

klasa vs struktura

A

Klasa to typ referencyjny zorientowany na przechowywanie
wartości bardziej złożonych i ukierunkowany na
odwzorowywanie pewnej hierarchii przy użyciu hermetyzacji,
dziedziczenia i mechanizmów używanych w konstrukcji
dynamicznych struktur danych.

Struktura to typ wartościowy zorientowany na
przechowywanie wartości, która jest nieco bardziej
rozbudowana od typów pierwotnych (int, double, etc.)
i nie zajmuje więcej niż 16 bajtów na stosie

Dwie zmienne typu klasa (obiekty) są traktowane jako równe
gdy są tego samego typu i odwołują się dokładnie do tego
samego obiektu – obszaru na stercie (sposób działania
porównania można zmienić).

Dwie zmienne typu struktura, rekord i rekord struktury są
traktowane jako równe gdy są tego samego typu, a wartości
ich pól są sobie równe.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

rekord (klasy) vs rekord struktury

A

Rekord (record class) to typ referencyjny zorientowany na
przechowywanie wartości bardziej złożonych, ale raczej
niezmiennych - przeznaczonych głównie do odczytu.
Takimi danymi są np. dane statystyczne. W deklaracji można
pisać record lub record class.

Rekord struktury to typ wartościowy – niereferencyjny.
W deklaracji pisze się record struct. Rekord struktury,
w przeciwieństwie do rekordu, jest przeznaczony do
przechowywania danych, które mogą się zmieniać.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

Tablice

A

Tablice to zbiory wielu zmiennych tego samego typu.
Tablice umożliwiają przeprowadzanie operacji
na grupach obiektów.
Typ elementów tablicy wskazywany jest
z chwilą jej deklaracji.
Przydział pamięci na stercie dla określonej liczby elementów
następuje w momencie tworzenia tablicy. Są typami
referencyjnymi.
Istnieją tablice jednowymiarowe, wielowymiarowe
oraz tablice o różnej liczbie elementów w wierszach
lub kolumnach.
W tablicach oprócz typów wbudowanych można
przechowywać również klasy i struktury itd.
Każda tablica dziedziczy po abstrakcyjnej klasie
System.Array, która dostarcza podstawowych mechanizmów
do działania na elementach tablicy.
Do deklaracji tablicy służy operator [].
Tablice są indeksowane od wartości „0” do „n-1”, gdzie n to
liczba elementów tablicy
Do tworzenia bardziej złożonych i wyspecjalizowanych
struktur danych oraz efektywnego zarządzania nimi służą
kolekcje (inny wykład).

int[,] t4 ; //deklaracja bez alokacji
int[,] t5= new int[3,2]; //alokacja
dwu wymiarowe tablice ^
int[][] <- tez dwuwymiarowa

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Predykaty wyszukiwawcze
co to?
jak deklarować?

A

Wyszukiwanie w tablicach bazuje na predykatach
wyszukiwawczych - metodach definiujących kryteria wysz.

Predykaty wyszukiwawcze można deklarować w wygodny
sposób z wykorzystaniem wyrażeń lambda.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

Wyrażenia lambda
co to?
co zawiera?
jak można przekazywać argumenty?

A

Wyrażenia lambda to maksymalnie
uproszczone metody anonimowe.
Wyrażenia lambda zawierają jedynie
listę parametrów i ciało metody.
Wyrażenia lambda nie mają nazwy
oraz nie definiują typu zwracanego.

Gdy wyrażenie lambda przyjmuje jeden argument,
nie trzeba otaczać go nawiasami ().
Gdy ciało funkcji zawiera tylko jedną instrukcję, nie trzeba
używać klamerek {} ani słowa kluczowego return.
Zmienne zdefiniowane w ciele wyrażenia lambda
są usuwane po zakończeniu działania metody.
Można przekazywać do wyrażeń lambda parametry
poprzez referencję i wyjście.

Nie trzeba podawać typów parametrów dla zmiennych
przekazanych przez wartość, natomiast wymagane jest
podanie typu parametru dla zmiennych przekazanych
przez referencję i wyjście.
Zwracane wartości muszą pasować do kontekstu użycia
(typu danego delegata).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

Func<>
co to?
co posiada?
Jakie parametry?
przeciazanie
Typy parametrow

A

Func<> jest delegatem generycznym, zatem jest osadzony
na wskazanych typach parametrów wejściowych
i wyjściowych.

Ma zero lub więcej parametrów wejściowych i dokładnie
jeden parametr wyjściowy. Jest to parametr ostatni.

Func<> można definiować bezpośrednio w kodzie.

Func<> wymaga podania typu parametrów oraz typu
zwracanego wyniku (ostatni parametr).

Func<> dysponuje konstruktorem przeciążonym 17 razy, tj.
Func<out>, Func<in, out>, Func<in1, in2, out>, Func<in1,
in2, in3, out> itd.</out>

nie da się przeciążać funkcji zadeklarowanej za pomocą func

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

Action<>
co to?
co posiada?

A

Action<> jest delegatem generycznym, który bazuje
wyłącznie na parametrach wejściowych (musi posiadać co
najmniej 1)- nie posiada on parametrów wyjściowych.

Action<> w pozostałych kwestiach jest zbliżony do Func<>.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

Testy jednostkowe (ang. unit test)

A

Testy jednostkowe (ang. unit test) to metoda testowania
tworzonego oprogramowania polegająca na przygotowaniu
i wykonaniu dedykowanych testów.
Test jednostkowy wywiąże się z wykonaniem testowanego
fragmentu kodu i porównaniem wyniku z ustalonym przez
autora testu wynikiem wzorcowym (np. czy metoda Dodaj()
dla argumentów 2 i 2 powinna zwrócić 4).

Test jednostkowy to (inaczej) kod wykonujący inny kod
w warunkach kontrolowanych, który służy do weryfikacji
poprawności tego drugiego.
Testy jednostkowe pozwalają automatyzować proces
tworzenia oprogramowania, są zatem podstawą wielu
podejść do tworzenia oprogramowania (np. ekstremalnego).
Autor testu dostarcza dane wejściowe oraz informację
o oczekiwanym rezultacie, celem testu jest porównanie
rezultatu oczekiwanego z rezultatem otrzymanym.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
NuGet
NuGet jest systemem zarządzania pakietami w postaci rozszerzenia do Visual Studio, ułatwiającym zarządzanie referencjami do bibliotek. Realizuje kłopotliwe i czasochłonne operacje: (0)wyszukania po nazwie odpowiedniej biblioteki, (1)ściągnięcia jej, (2)rozpakowania, (3)dodania referencji oraz (4)aktualizacji pliku konfiguracyjnego. Realizuje też operację usuwania. Biblioteki konfiguruje się niezależnie w kontekście poszczególnych aplikacji.
26
Testy jednostkowe Dobre praktyki
T.j. należy pisać dla każdej metody, która reprezentuje jakąś funkcjonalność. T.j. powinny pokrywać całą funkcjonalność metody. T.j. powinny być niezależne od siebie i od środowiska, w którym są wykonywane. Należy unikać sytuacji, w których wynik jednego testu zależy od wyniku innego testu. T.j. powinny być szybkie i działać w izolacji. T.j. nie powinny korzystać z sieci, bazy danych lub innych zewnętrznych źródeł danych. T.j. powinny być łatwe do zrozumienia i utrzymania. Należy dbać o czytelność kodu testów i komentarze. T.j. powinny być uruchamiane automatycznie za pomocą dedykowanych narzędzi. T.j. nie eliminują wszelkich problemów w kodzie, ale są jednym z narzędzi, które pomaga w poprawie jego jakości. T.j. powinny być pisane równolegle z kodem produkcyjnym. Nie należy zostawiać ich pisania na koniec, ponieważ może to prowadzić do wykrycia problemów na późnym etapie, co może skutkować koniecznością przebudowy już napisanego kodu. T.j. należy uruchamiać regularnie i śledzić ich wyniki. W przypadku pojawienia się błędów, należy jak najszybciej je naprawić. T.j. powinny być pisane z myślą o ich czytelności i możliwości ponownego użycia. Mogą być one cennym źródłem informacji dla programistów, którzy będą pracować z danym kodem w przyszłości. T.j. powinno umieszczać się w tym samym rozwiązaniu, co właściwa aplikacja, ale w oddzielnym projekcie (szablon: projekt testowy NUnit) <-był komentarz. W przykładzie klasa testująca została dla uproszczenia dodana do wspólnego projektu (tj. biblioteka klas, interfejs1, interfejs2, etc.).
27
Klasa Mock
Klasa Mock (mock to imitacja) z biblioteki Moq lub NSubstitute umożliwia tworzenie obiektów zastępczych, które pozwalają na ścisłe kontrolowanie zachowania innych obiektów podczas testów Użycie klasy Mock jest ważne, ponieważ rzeczywiste obiekty mogą być skomplikowane w implementacji: ich zachowanie nie jest pewne, ich tworzenie jest pracochłonne, ich tworzenie może prowadzić do problemów związanych z zależnościami między klasami. Użycie Mock ułatwia zatem testowanie i eliminuje niepożądane skutki uboczne tworzenia obiektów rzeczywistych. Klasy Fake są często używane do testowania całych systemów, klasy Stub są przydatne w testowaniu jednostkowym, klasy Spy pozwalają wywoływać rzeczywiste metody dla oryginalnego obiektu i jego atrapy. Innymi klasami pozwalającymi tworzyć obiekt zastępcze są np.: klasa Fake z biblioteki FakeItEasy, klasa Stub z biblioteki Rhino.Mocks, klasa Spy z biblioteki Mockito.NET, etc.. Obiekty zastępcze eliminują konieczność użycia zasobów zewnętrznych (baz danych, strumieni, etc.). Przykładowo mogą one symulować działanie bazy danych i zwracać odpowiednie dane testowe.
28
Test-driven development (TDD)
Na bazie testów powstała technika tworzenia oprogramowania Test-driven development (TDD). TDD polega na wielokrotnym powtarzaniu sekwencji kroków: Krok 1/3. Napisanie testu sprawdzającego dodawaną funkcjonalność, który wykazuje błąd, bo funkcjonalność początkowo nie istnieje. Krok 2/3. Implementacja funkcjonalności, która powinna przejść pomyślenie test. Krok 3/3. Refaktoryzacja kodu, by spełniał określone standardy.
29
string jaki typ? Jak traktowany? modyfikacja Jak wywoływane metody?
Każda operacja na ciągu wymusza tworzenie nowego obiektu typu string. Zatem kod np. string s=”a”; s=”b”; tworzy po sobie dwie nowe instancje s w pamięci. Zatem zmiennych string nie powinno się często modyfikować, gdyż obniża to wydajność (przy licznych modyfikacjach należy stosować StringBuilder- cd. wykładu). Klasa string jest typem referencyjnym (dziedziczy po System.Object), ale jej obiekty deklaruje się jak zmienne typów prostych (w typowych zastosowaniach nie używa się new). W C++ obiekty klasy std::string są typami wartościowymi. W przeciwieństwie do pozostałych typów referencyjnych typ „string” jest w języku C# traktowany jak typ prosty (choć jest referencyjny), a zatem może być deklarowany jako stała i może mieć przypisywane stałe wartości typu string. Zmiennej string przypisuje się wartość stałą na dwa sposoby: jako stałe dosłowne @”tekst” oraz stałe standardowe ”tekst”. Wyjątkiem przy ciągach dosłownych jest znak "", który jest zamieniany na ". Metody klasy string można wywoływać na dwa sposoby: z poziomu instancji (obiektu) lub jako statyczne.
30
Interpolowany ciąg znaków jest oznaczany znakiem specjalnym
Interpolowany ciąg znaków jest oznaczany znakiem specjalnym $. Można łączyć z @ Interpolowany ciąg znaków może zawierać wyrażenia, które są finalnie zmieniane w ciąg znaków. (wstawianie do stringu czegoś)
31
string a = null vs string a = string.Empty
Przypisanie null oznacza, że nie znamy wartości. Przypisanie Empty oznacza, że znamy wartość, ale nie dotyczy ona inicjalizowanej zmiennej.
32
string.Copy() vs string.Clone()
Copy() kopiuje zmienną w pamięci, Clone() tworzy tylko kopię referencji.
33
string porównywanie
Porównanie przez Equals lub operator „==” – podejścia nie pozwalające zdefiniować dodatkowych opcji: np. ignorowania wielkości liter, ustawień regionalnych etc. Porównanie CompareTo – niestatyczna metoda porównująca zmienne string bez możliwości definiowania dodatkowych opcji. Porównanie Compare – statyczna metoda porównująca zmienne string z możliwością definiowania dodatkowych opcji Porównanie CompareOrdinal – statyczna metoda porównująca zmienne string na podstawie ich kodów ASCII (kodów liczbowych) bez możliwości definiowania dodatkowych opcji (zwraca np. wartość 32 w przypadku porównania litery a i A).
34
StringBuilder po co? co reprezentuje? jak zamienić na string?
Każda zmiana zmiennej string wiąże się z przepisaniem ciągu znaków do nowego obszaru na stercie. Jest to największa wada obiektów typu string. Gdy przewiduje się częstą modyfikację ciągów znaków zaleca się stosowanie klasy System.Text.StringBuilder. Obiekt klasy StringBuilder reprezentuje tablicę znaków o zmiennej długości: rezerwuje w pamięci pewien obszar roboczy, na którym można wykonywać operacje. Konstruktor klasy StringBuilder pozwala wskazać: - początkowy rozmiar tablicy znaków (capacity), - dopuszczalny rozmiar tablicy znaków (maxCapacity) lub/i - ciąg znaków inicjalizujący tablicę znaków (value). Wywołanie metody ToString() dla obiektu klasy StringBuilder powoduje przekonwertowanie tablicy znaków do zmiennej string.
35
StringBuilder Zestawienie ważniejszych metod Append() AppendFormat() AppendLine() Insert() Remove() Replace() ToString() Clear()
Append() dodaje tekst na końcu obszaru obiektu StringBulider AppendFormat() dodaje tekst wraz z formatowaniem (analogicznym jak dla Console.Write()) na końcu obszaru obiektu StringBulider AppendLine() wstawia znak końca linii Insert() wstawia ciąg znaków we wskazanym miejscu Remove() usuwa wskazaną część ciągu znaków Replace() zamienia wskazaną część łańcucha znaków ToString() konwertuje tablicę znaków do string Clear() usuwa aktualną zawartość obiektu
36
Regex
Wyrażenia regularne (ang. REGular EXpressions) stosuje się tam, gdzie nie ma możliwości użycia klas string i charnp. przy sprawdzeniu, czy nazwa pliku pasuje do wzorca. Wyrażenia regularne można wyeliminować, ale zastępczy kod jest: długi, nieczytelny, podatny na błędy i nieelastyczny. Wyrażenia regularne pozwalają efektywnie zarządzać fragmentami ciągów znaków, które są dopasowane do wskazanego wzorca. Wyrażenia regularne mogą być także wykorzystywane w walidacji wprowadzanych danych Klasa Regex określa wyrażenia regularne do reprezentowania wzorców ciągów znaków. Klasa Regex definiuje metody do przeszukiwania, wydobywania i zastępowania tekstu. Metody klasy Regex można wywoływać z poziomu instancji lub jako statyczne.
37
Regex scenariusze użycia IsMatch Match NextMatch Matches Replace Split Escape Unescape
Walidacja dopasowania (IsMatch) pozwala sprawdzić, czy wzorzec jest obecny. Pobranie pierwszego (jednego) dopasowania (Match), potem kolejnych (Match.NextMatch). Pobranie wszystkich dopasowań (Matches, zwraca MatchCollection). Zastąpienie dopasowań (Replace). Dekompozycja dopasowań (Split) na tablicę. Zastąpienie znaków {\, *, +,?, |, {, [, (,), ^, $, ., # oraz białych} przez ich odpowiedniki traktowane dosłownie (Escape). Przykładowo znak ' * ’ jest zastępowany przez ‘ \ \ * ’, dzięki czemu przestaje być np. przez obiekty Regex traktowany jako „0 lub wiele wystąpień”. Realizacja odwrotna do przedstawionej wyżej (Unescape).
38
Lazarus
Lazarus (http://www.lazarus-ide.org) to zintegrowane środowisko programistyczne oparte na kompilatorze Free Pascal i wzorowane na Delphi. Lazarus bazuje na założeniu, aby raz napisana aplikacja kompilowała się wszędzie (write once compile anywhere), czyli na różne platformy. Jest to podejście odmienne od tego, aby raz napisana aplikacja działała wszędzie (write once run anywhere).
39
GRASP
Zasady GRASP są uzupełnieniem zasad SOLID. Zasady GRASP (ang. General Responsibility Assignment Software Patterns, ogólne wzorce ustalania odpowiedzialności w oprogramowaniu) określają odpowiedzialność klas i obiektów w systemie. Każda zasada GRASP wyjaśnia inny problem dotyczący ustalania odpowiedzialności.
40
Zasada Creator
Zasada Creator określa kiedy obiekt powinien tworzyć inny obiekt. Rozwiązanie: klasie B należy przypisać odpowiedzialność za tworzenie obiektów klasy A jeśli: (a) zawiera ona lub agreguje obiekty klasy A. (b) blisko współpracuje ona z klasą A. (c) ma ona dane inicjalizacyjne potrzebne do tworzenia obiektów klasy A. Im więcej wymienionych punktów jest spełnionych, tym lepszym wyborem jest wybór klasy B. Zasada jest istotna, ponieważ jej stosowanie redukuje liczbę powiązań między obiektami i niepotrzebnych wywołań.
41
Zasada Information Expert
Zasada Information Expert pozwala ustalać zakres odpowiedzialności obiektu. Rozwiązanie: zadanie należy przypisać tej klasie, która ma informacje niezbędne do jego wykonania. Komentarz: (a) należy określić, jakie dane są niezbędne do zrealizowania nowej funkcjonalności oraz (b) delegować nową odpowiedzialność do klasy zawierającej najwięcej informacji potrzebnych do wykonania tej funkcjonalności.
42
Zasada Controller
Zasada Controller określa, który obiekt (część logiki biznesowej) powinien komunikować się z graficznym interfejsem użytkownika (GUI). dobrym przykładem na spełnienie tej zasady jest wzorzec model-widok-kontroler (MVC). We wzorcu MVC zadania interfejsu użytkownika są obsługiwane przez kontroler. Kontroler odbiera informacje od GUI, wykonuje niezbędne operacje i zwraca wynik do GUI (np. przeglądarki).
43
Zasada niskiego powiązania (Low Coupling)
Zasada niskiego powiązania (Low Coupling) sugeruje, by projektując klasę zmniejszać liczbę powiązań z innymi klasami, aby ewentualne zmiany w tej klasie nie wymuszały zmian w klasach powiązanych. Duża liczba powiązań klasy z innymi klasami wskazuje na potrzebę zmian w strukturze klas (np. reorganizację lub agregację klas).
44
Zasada wysokiej spójności (High Cohesion)
Zasada wysokiej spójności (High Cohesion) wskazuje by ograniczać zakres odpowiedzialności obiektu - powinien mieć on klarowną strukturę i cel, by był zrozumiały i łatwy w utrzymaniu. Każdy obiekt powinien się skupiać tylko na jednej odpowiedzialności. Nie należy tworzyć klas i obiektów odpowiedzialnych za dużą część logiki aplikacji - przeciążone klasy należy dzielić na kilka mniejszych.
45
Zasada polimorfizmu
Zasada polimorfizmu sugeruje by funkcjonalność klas dostosowywać do specyfiki tych klas. Na polimorfizm można spojrzeć szerzej i wskazać cztery główne typy polimorfizmu: A. Polimorfizm podtypu bazuje na użyciu dziedziczenia i dostosowania działania metod do specyfiki typu. B. Polimorfizm przymusu (rzutowanie) to bezpośrednie przekształcanie jednego typu w drugi w wyniku rzutowania typów – konwersji jawnej i niejawnej. C. Polimorfizm parametryczny (przeciążenie) zapewnia sposób użycia jednej nazwy funkcji dla różnych kompletów parametrów wywołania. D. Polimorfizm ad hoc zapewnia możliwość działania zależnego od typu, jak w przypadku przeciążania operatorów.
46
Zasada klarownej produkcji (Pure Fabrication)
Zasada klarownej produkcji (Pure Fabrication) określa gdzie delegować zadania, gdy nie można wskazać pojedynczej klasy dla oczekiwanej funkcjonalności (uwzględniając inne zasady). Należy wówczas utworzyć nową klasę pomocniczą, która nie posiada jednoznacznej interpretacji z zawiera oczekiwaną funkcjonalność.
47
Zasada Indirection
Zasada Indirection określa jak organizować komunikację między obiektami, aby ich mocno nie wiązać. Należy przypisać te odpowiedzialności do nowego obiektu pośredniego przeznaczonego do komunikacji obiektów (klas/komponentów/usług/pakietów), które nie muszą być od siebie bezpośrednio zależne. Przykładowo, pewna klasa może potrzebować danych z bazy danych, ale nie musi implementować komunikacji- tę funkcjonalność można zaimplementować w klasie pośredniej.
48
Zasada chronione wariacje (Protected Variations)
Zasada chronione wariacje (Protected Variations) określa jak przypisywać odpowiedzialność, aby zmiana w jednej części systemu nie powodowała niestabilności innych elementów. Należy typować punkty niestabilności systemu i narzucać w nich odpowiednią odpowiedzialność przez stosowanie interfejsów. Przykładowo, mechanizm logowania przez system Google jest wygodny dla użytkowników, ale regularnie się zmienia. Stosowanie po stronie systemu interfejsu i klasy menagera ogranicza zakres zmian przy aktualizacji sposobu logowania.
49
DRY
DRY (nie powtarzaj się, ang. Don’t Repeat Yourself) to wzorzec, który mówi, że należy unikać powtarzania tych samych części kodu w różnych miejscach systemu (klas, struktur, funkcji, modułów, bibliotek itd.). Wzorzec DRY odnosi się również do unikania powtórzeń często wykonywanych czynności, które powinny być realizowane przez stosowne automaty: szablony, makra, generatory kodu, skrypty itd.
50
KISS
KISS (niech to będzie możliwie proste, ang. Keep It Simple, Stupid) to reguła mówiąca, że nie należy w programowaniu na siłę komplikować rzeczy prostych. Reguła KISS dotyczy np. dążenia do stosowania wszędzie wzorców projektowych, nawet w klarownych obszarach zastosowań. Czas potrzebny na wdrożenie wzorca może być bowiem znacznie dłuższy, niż czas potrzebny na wykonanie zadania w sposób standardowy.
51
Zasada RoT
Zasada RoT (reguła trzech, ang. Rule of Three) mówi, że jeśli istnieją trzy kopie tego samego kodu, należy zastosować regułę DRY i połączyć kod. Pozwala to chronić program przed wprowadzaniem zmian w trzech miejscach (w razie potrzeby), co może powodować dużą liczbę nowych problemów. Zasada RoT pozwala godzić zasadę DRY (unikać powtórzeń) i zasadę KISS (unikać utrudnień).
52
Zasada SoC
Zasada SoC (separacja zagadnień, ang. Separation of Concern, SoC) polega na podziale programu na odrębne moduły, których funkcjonalność pokrywa się tak mało, jak to tylko możliwe. Zasada SoC upraszcza pracę grupową (każdy pracownik pracuje nad swoim modułem), ułatwia rozbudowę systemu, poprawia czytelność kodu itd. Zasada SoC dotyczy nie tylko kodu, ale także architektury systemu, np. jego podziału na warstwy (prezentacji, logiki biznesowej, dostępu do danych, bazy danych, np. MVC).
53
Zasada YAGNI
Zasada YAGNI (nie będziesz tego potrzebował, ang. You Ain’t Gonna Need It) mówi, że nie należy pisać oprogramowania, które nie jest potrzebne, ale wydaje się, że może się kiedyś przydać. Zasada YAGNI uwzględnia fakt, że w trakcie rozwoju projektu najczęściej zmieniają się początkowe założenia.
54
MoSCoW
MoSCoW (ang. M — Must have it, S — Should have it, C — Could have if not affecting other things, W — Won’t have this time) to metoda, która zaleca podział wymagań klienta na kilka podgrup: te, które musi mieć (M), te, które powinien mieć (S), te, które może mieć, jeżeli nie zaszkodzą tworzeniu gotowych funkcjonalności (C), te, których nie uda się zaimplementować w danym terminie (W). Metoda MoSCoW dobrze uzupełnia się z zasadą YAGNIi pozwala porządkować priorytety zadań.
55
Strumienie są wykorzystywane do
Strumienie są wykorzystywane do odczytu i zapisu informacji. Strumienie przetwarzają dane pochodzące z różnych źródeł: pliku, pamięci, sieci, urządzenia współpracującego z portem wejścia-wyjścia etc. Obsługę strumieni w C# zapewniają klasy z przestrzeni nazw System.IO. Klasy reprezentujące strumienie danych są pochodnymi klasy abstrakcyjnej Stream.
56
BinaryReader BinaryWriter BufferedStream FileStream MemoryStream NetworkStream StreamReader/ StreamWriter StringReader/ StringWriter
BinaryReader służy do odczytu dowolnych danych binarnych ze strumienia binarnego BinaryWriter służy do zapisu danych w formacie binarnym BufferedStream zapewnia buforowanie przy odczycie i zapisie do strumienia docelowego (zwiększa wydajność) FileStream służy do odczytu i zapisu pliku na dysku MemoryStream służy do odczytu i zapisu z pamięci operacyjnej (ewentualnie zewnętrznej) NetworkStream służy do odczytu i zapisu z urządzeń w sieci StreamReader/ StreamWriter służy do odczytu/ zapisu danych tekstowych ze strumienia binarnego StringReader/ StringWriter służy do odczytu/ zapisu z bufora (StringBuilder) ciągu znaków
57
Klasa Stream co definiuje? co tworzy?
Klasa Stream definiuje uniwersalne składowe do pracy ze strumieniami. Klasa Stream tworzy poziom abstrakcji nad konkretnym źródłem danych i zapewnienia przetwarzanie danych z tego źródła niezależnie od jego specyfiki (sprzętowej). Klasa Stream uwalnia od konieczności projektowania i implementowania mechanizmów dedykowanych dla poszczególnych źródeł danych (urządzeń). Klasa Stream zapewnia trzy podstawowe typy operacji związanych z przetwarzaniem strumieni: czytanie, zapisywanie i przeszukiwanie.
58
Strumienie CanRead CanSeak CanWrite Length Position Close Flush Read ReadByte SetLength Seek Write WriteByte
CanRead CanSeak CanWrite Właściwości Określają, czy dany strumień obsługuje odpowiednio czytanie, przeszukiwanie i zapisywanie danych Length Właściwość Zwraca długość strumienia wyrażoną liczbą bajtów Position Właściwość Zwraca lub ustawia pozycję w ramach bieżącego strumienia Close Metoda Zamyka bieżący strumień i zwalnia powiązane z nim zasoby Flush Metoda Opróżnia pomocniczy bufor i zapisuje dane w wykorzystywanym urządzeniu (np. pliku) Read Metoda Odczytuje ze strumienia sekwencję bajtów i przenosi pozycję w strumieniu zgodnie z liczbą odczytanych bajtów. Zwraca liczbę odczytanych bajtów lub wartość -1, gdy osiągnięto koniec strumienia. ReadByte Metoda Odczytuje jeden bajt SetLength Metoda Ustawia długość danego strumienia, może być wykorzystywana do rozszerzania lub skracania strumieni Seek Metoda Ustawia pozycję w ramach bieżącego strumienia poprzez wyszukanie Write Metoda Zapisuje sekwencję bajtów WriteByte Metoda Zapisuje jeden bajt
59
Convert
Klasa Convert pośredniczy w konwersji między typami.
60
kodowanie znakow
Unicode to popularny standard, który znakom przypisuje wartość liczbową. Kodowanie w ramach standardu zapewnia zapis wartości liczbowej do postaci bitowej. Przykładowe kodowania to: UTF, UTF-8, UTF-16 i UTF-32. Inne standardy (oprócz Unicode): ASCII (lata sześćdziesiąte, tylko 127 znaków), ANSI/ISO-8859 (tylko 256 znaków), etc. W UTF-32 za zakodowanie każdego znaku potrzeba 4. bajtów. Wadą jest marnowanie miejsca przy kodowaniu początkowych znaków Unicode. W UTF-8 kodowane znaki nie mają stałej długości, lecz mogą mieć od 1 do 6 bajtów. Pierwsze znaki Unicode są kodowane na jednym bajcie i są one identyczne z kodem ASCII. W C# w przestrzeni nazw System.Text można znaleźć różne klasy pośredniczące w przekodowywaniu.
61
wybór pomiędzy podejściem synchronicznym oraz asynchronicznym
Instrukcja wykonywana synchronicznie blokuje działanie programu do momentu jej wykonania. Gdy jest to pobranie danych ze strumienia lub klawiatury nie wiadomo, jak długo taka blokada potrwa. Instrukcja wykonywana asynchronicznie wykonuje się w tle, dzięki czemu inne działania w aplikacji nie są blokowane. W wywołaniu asynchronicznym zwykle istnieje jakaś funkcja zwrotna, która wykonuje się automatycznie po zakończeniu zadania asynchronicznego. oznaczenie metody jako async i uzycie await
62
Klasa MemoryStream służy do
Klasa MemoryStream służy do zapisywania i odczytywania bajtów z pamięci operacyjnej. Klasa MemoryStream może pełnić funkcję klasy pomocniczej, jeśli dane musiałyby być poddane dodatkowej obróbce.
63
Klasa BufferedStream wprowadza
Klasa BufferedStream wprowadza bufor pośredniczący w zapisie i odczycie (operacjach wejścia - wyjścia). Bufor jest opróżniany a dane z niego zapisane w chwili jego 1. zapełnienia lub w odpowiedzi na 2. żądanie zamknięcia. Domyślna pojemność bufora wynosi 4096 bajtów. Obiekty klasy BufferedStream są wykorzystywane do podnoszenia wydajności operacji odczytu bajtów z portów wejścia-wyjścia i sieci komputerowych
64
Klasy StreamReader i StreamWriter zaprojektowano do pracy z co rozszerzają?
Klasy StreamReader i StreamWriter zaprojektowano do pracy z danymi tekstowymi (nie binarnymi). Klasy StreamReader i StreamWriter rozszerzają abstrakcyjne klasy TextWriter i TextReader do odczytu i zapisu tekstu w formie całych wierszy znaków.
65
Wybrane metody StreamReader WriteLine Write Peek() Read( ) Read(char [] bufor, int indeks, int liczba) ReadLine( ) ReadToEnd( )
WriteLine Działa z łańcuchami znaków, dołącza dynamicznie znak nowego wiersza ("\n"). Write Metoda nie dołącza znaku nowego wiersza i służy do zapisu ciągów znaków oraz wartości typów prostych w formie ciągów znaków. Peek( ) Zwraca kolejny dostępny znak (liczbę całkowitą) bez zmiany pozycji w strumieniu wejściowym lub liczbę -1, jeśli strumień nie zawiera już znaków. Read( ) Odczytuje ze strumienia tekstowego kolejny znak. Read(char [] bufor, int indeks, int liczba) Odczytuje określoną liczbę znaków zapisywanych w tablicy znakowej począwszy od przekazanego indeksu. ReadLine( ) Odczytuje łańcuch znaków złożony z pojedynczego wiersza tekstu. ReadToEnd( ) Odczytuje wszystkie znaki, począwszy od bieżącej pozycji i skończywszy na końcu strumienia.
66
Klasy StringReader i StringWriter pełnią funkcję
Klasy StringReader i StringWriter pełnią funkcję podobną do klas StreamReader i StreamWriter. Klasy StringReader i StringWriter współpracują jednak ponadto z klasą StringBuilder, która rezerwuje obszar pamięci na ciąg znaków bez konieczności jego przepisywania po każdej wprowadzonej zmianie.
67
Serializacja i deserializacja Do czego służy? Jak oznaczać co jest serializowane?
Serializacja i deserializacja są mechanizmami wspomagającymi przesyłanie obiektów przez sieć, przechowywanie ich w pliku lub bazie danych, etc. Serializacja służy do pobierania stanu obiektu i umieszczania go w strumieniu bajtów lub dokumencie XML, deserializacja jest procesem odwrotnym. Składowe klasy [Serializable], które nie powinny być serializowane, muszą być oznaczone atrybutem [NonSerialized] Serializacji podlegają publiczne: pola i właściwości. Pola prywatne lub chronione mogą podlegać serializacji, ale należy dla nich zaimplementować publiczną właściwość. Właściwości tylko do odczytu nie są serializowane. Serializacji mogą podlegać obiekty standardowych klas kolekcji (np. „List”). Serializacja i deserializacja bazują na określonych formatach: XML (Extensible Markup Language, rozszerzalny język znaczników; klasa XmlSerializer), binarnym (klasa BinaryFormatter) oraz SOAP (Simple Object Access Protocol, protokół komunikacyjny wykorzystujący XML na potrzeby aplikacji internetowych; klasa SoapFormatter).
68
File i Directory vs FileInfo i DirectoryInfo
Klasy File i Directory są klasami statycznymi, zaś FileInfo i DirectoryInfo nie są klasami statycznymi. Klasy File i Directory powinny być używane w przypadku konieczności wykonania pojedynczych operacji wejścia/wyjścia. Klasy FileInfo i DirectoryInfo powinny być używane w przypadku konieczności wykonania wielu operacji wejścia/ wyjścia: tworzenia, usuwania, modyfikacji, etc. Obiekty klas FileInfo i DirectoryInfo zapewniają wygodniejszy dostęp do szczegółowych informacji o przetwarzanych plikach i folderach, których pozyskiwanie z wykorzystaniem File i Directory jest mniej wygodne.
69
Klasa Form Co reprezentuje? Po czym dziedziczy?
Klasa Form reprezentuje okno, okno dialogowe, okno MDI (ang. multi document interface) itd., składające się na interfejs użytkownika. Form dziedziczy po klasie Control, więc posiada właściwości podstawowe, które decydują m.in. o: rozmiarze formularza, położeniu, wymiarach, kolorach, obrazku wyświetlanym w tle, tekście i kroju fontów, widoczności, etc. (tabela dalej). Klasa Form dziedziczy po klasie Control, co zapewnia także obsługę zdarzeń związanych z obsługą myszy i klawiatury, które informują m.in. o stanie przycisków myszy, stanie przycisków Shift, Ctrl i Alt, wyglądzie kursora myszy, pozycji kursora itd. (tabela dalej).
70
Klasa Application
Klasa Application zawiera metody i właściwości do zarządzania aplikacją, służące m.in. do pobierania informacji o aplikacji, uruchamiania i zatrzymywania aplikacji, przetwarzania komunikatów systemu Windows itd. Klasa ta nie może być dziedziczona
71
Formularz to
Formularz to obiekt reprezentujący fragment powierzchni ekranu (zwykle prostokątny), na którym można wyświetlać informacje dla użytkownika lub je od niego pobierać. Formularz może być zwykłym oknem, oknem multiple document interface (MDI), oknem dialogowym lub obszarem wyświetlania dla procedur graficznych. Najprostszym sposobem definiowania interfejsu użytkownika jest umieszczenie na formularzu (formularzach) kontrolek.
72
właściwości dziedziczone po Control Size Location Width, Heigth, Top, Bottom, Left, Right TabIndex Visible MouseButtons MousePosition ModifierKeys
Size - wysokość, szerokość kontrolki Location - typu Point współrzędne lewego górnego rogu Bottom - suma Height i Top Right - suma Left i Width TabIndex - pozycja kontrolki na liście elementów kontenera Visible - czy ma być widoczne MB - stan przycisków MP - Point reprezentuje pozycje kursora MK - który klawisz modyfikatora (Shift, Ctrl, Alt) jest wciśnięty
73
Właściwości klasy Form MaximizeBox MinimizeBox ClientSize DesktopLocation MinimumSize WindowState
Max Min - czy przyciski maksymalizacji i minimalizacji są wyświetlane ClientSize - rozmiar bez obramówki i paska DesktopLocation - położenie formularza względem puplitu MinimumSize - typu Size minimalny rozmiar, 0, 0 brak rozmiaru WindowState - jak ma być wyświetlany formularz po uruchomieniu
74
czym jest sterowana aplikacja oparta na formularzach? na co czeka aplikacja?
Aplikacja oparta na formularzach jest sterowana zdarzeniami. W odróżnieniu od programów wsadowych (a wśród nich konsolowych), aplikacja większość czasu oczekuje na czynności użytkownika, np. wypełnienie pola edycyjnego lub naciśnięcie przycisku, czyli na zdarzenie.
75
zdarzenia myszka Button Clicks Delta X,Y
Button - który przycisk został wcisnięty Clicks - ile kliknięć Delta - obroty scrolla X,Y - współrzędne kursora
76
KeyPressEventArgs Właściwości KeyCode KeyData Alt,Control,Shift Modifiers
KC - kod klawisza typu Keys KD - kod klawisza typu Keys może być więcej niż jeden A,C,S - czy był wciśnięty Modifiers - czy była wciśnięta kombinacja klawiszy A,C,S
77
Delegata EventHandler Co reprezentuje?
Delegata EventHandler reprezentuje metody, które mogą obsługiwać zdarzenie.
78
Referencja Object sender wskazuje na referencja EventArgs e jest wykorzystywana do
Referencja sender wskazuje na źródło zdarzenia (np. kontrolkę, która wywołała zdarzenie), zaś referencja e jest pomocniczo wykorzystywana w nieszablonowej obsłudze zdarzeń i wówczas może zawierać dodatkowe informacje o zdarzeniu.
79
Standardowa aplikacja jest ilu wątkowa?
Standardowa aplikacja jest jednowątkowa – pojedynczy wątek obsługuje logikę aplikacji oraz zdarzenia
80
Komunikaty co robią? gdzie przechowywane? jak przetwarzane? odmiany
Komunikaty sygnalizują wiele zdarzeń, wywołanych przez użytkownika, system operacyjny lub inne aplikacje. Komunikaty przechowywane są w strukturze danych typu kolejka i zgodnie z nią przetwarzane. Komunikaty przetwarzane są w pętli, do czasu wystąpienia komunikatu WM_QUIT sygnalizującego zamknięcie aplikacji. Kontrolki występują w dwóch odmianach: widocznej i niewidocznej
81
BLL
BLL (Business Logic Layer) zawiera klasy modelu danych.
82
Zalety WPF w kontekście WinForms:
WPF jest nowszy, więc bardziej zgodny z obecnymi standardami. WPF jest używany w wielu nowych aplikacjach, np. w VS. WPF jest bardziej elastyczny, ma więcej kontrolek. XAML w WPF ułatwia edycję GUI i pozwala rozdzielać pracę designera (XAML) od programisty (C#). WPF używa przyspieszenia sprzętowego do rysowania GUI, co poprawia wydajność
83
Zalety WinForms w kontekście WPF:
WinForms jest starszy, ugruntowany w zastosowaniach. WinForms jest wspierany przez wiele zewnętrznych kontrolek komercyjnych i darmowych. WinForms dysponuje subiektywnie prostszym mechanizmem tworzenia formularzy.
84
Istnieje pięć typów poleceń SQL:
A. Język definicji danych (Data Definition Language). Create, Drop, Alter, Truncate B. Język manipulacji danymi (Data Manipulation Language). Insert, Update, Delete C. Język kontroli danych (Data Control Language). Grant, Revoke D. Język kontroli transakcji (Transaction Control Language). Commit, Rollback, Savepoint E. Język zapytań o dane (Data Query Language). Select
85
SSMS Co to? Co zapewnia?
SSMS to zintegrowane środowisko do zarządzania infrastrukturą SQL SSMS zapewnia narzędzia do konfigurowania, monitorowania i administrowania instancjami serwerów i bazami danych na tych serwerach. SSMS służy do wdrażania, monitorowania i uaktualniania składników warstwy danych używanych przez aplikacje oraz do tworzenia zapytań i skryptów.
86
ADO.NET
ADO.NET (ActiveX Data Objects for .NET) umożliwia dostęp w środowisku .NET do baz danych (Oracle, SQL Server, MySQL, etc.) przez zestaw dedykowanych klas. ADO.NET zapewnia dostęp nie tylko do danych z baz danych, ale także z arkuszy kalkulacyjnych, plików tekstowych, plików XML, etc.. ADO.NET bazuje na sterownikach dedykowanych dla konkretnych baz oraz sterownikach OLE DB (Object Linking and Embedding Database) lub ODBC (Open DataBase Connectivity), które są jednak mniej wydajne.
87
model połączeniowy vs bezpołączeniowy
Model połączeniowy jest oparty na odczytywaniu danych rekord po rekordzie (sekwencyjnym). Model połączeniowy wymaga utrzymywania połączenia między obiektem DataReader a źródłem danych. Model bezpołączeniowy realizuje pobierane danych ze źródła danych do lokalnego obiektu DataSet i przetwarzane ich na maszynie użytkownika. Przetworzone lokalnie dane są odsyłane do bazy danych w formie zestawu poprawek - połączenie nie jest utrzymywane.
88
SqlCommand Metoda ExecuteNonQuery() Metoda ExecuteScalar() Metoda ExecuteReader()
Metoda ExecuteNonQuery() klasy SqlCommand zwraca liczbę wierszy zmodyfikowanych działaniem operacji: Update, Insert, Delete. Metoda ExecuteScalar() klasy SqlCommand zwraca pojedynczą wartość, w szczególności otrzymaną np. w wyniku działania count, avg, min, max i innych funkcji agregujących. Metoda ExecuteReader() klasy SqlCommand zwraca wiele rekordów w wyniku selekcji danych. Współpracuje z obiektem klasy SqlDataReader.
89
Obiekt klasy SqlDataReader umożliwia
Obiekt klasy SqlDataReader umożliwia odczytywanie strumienia wierszy z bazy danych SQL Server.
90
Transakcja posiada następujące własności:
Transakcja jest niepodzielna (atomic) - wykonywane są wszystkie instrukcje nią objęte lub żadna. Transakcja nie zmienia integralności bazy danych (consistent). Transakcja musi być izolowana (isolated) - nie może powodować konfliktów z innymi transakcjami. Transakcja jest trwała (durable).
91
Obiekt SqlTransaction udostępnia m.in. 3 ważne metody:
BeginTransaction() do rozpoczęcia transakcji, Commit() do zatwierdzenia transakcji i Rollback() do wycofania transakcji.
92
Obiekt DataSet Co robi? Co odwzorowuje, w jaki sposób? Co umożliwia?
Obiektu DataSet buforuje rekordy na lokalnej maszynie klienta bez konieczności utrzymywania połączenia ze źródłem danych. Obiekt DataSet odwzorowuje strukturę relacyjnej bazy danych kodując: [A] hierarchiczny model obiektów - tabele, wiersze i kolumny oraz [B] ograniczenia i relacje. Obiekt DataSet zmniejsza obciążenie spowodowane stałym utrzymywaniem otwartego połączenia z bazą danych – może ona obsłużyć więcej użytkowników, co zwiększa skalowalność.
93
Interfejsy IEnumerable i IQueryable wspierają iterację po elementach kolekcji, ale różnią się podejściem do pobierania danych:
Interfejsy IEnumerable i IQueryable wspierają iterację po elementach kolekcji, ale różnią się podejściem do pobierania danych: pierwszy pobiera kolekcję rekordów i dopiero je filtruje, drugi filtruje kolekcję rekordów i dopiero je pobiera. Kod z IEnumerable wczytuje do pamięci z bazy danych całą kolekcję rekordów (np. 2000 rekordów) i wówczas (lokalnie) wybiera z nich te, które spełniają warunek (np. 20 rekordów). IEnumerable osoby = from o in db.Customers where o.Imie.Contains(‘a’) select o; Kod z IQueryable wczytuje do pamięci z bazy danych tylko te rekordy, które spełniają warunek (np. 20 rekordów z 2000). IQueryable osoby = from o in db.Customers where o.Imie.Contains(‘a’) select o;
94
Najważniejsze operatory zapytań LINQ Select Where Take Sum Min Max OrderBy Count First Last GroupBy
Select — wybiera z kolekcji odpowiedniego rodzaju dane (zbiory lub podzbiory danego obiektu) Where — zwraca obiekty spełniające dany warunek Take — jest używany do wybrania pierwszych n obiektów z kolekcji Sum — zwraca sumę Min — zwraca minimalną wartość Max — zwraca maksymalną wartość OrderBy — sortuje wyniki po wybranym elemencie kolekcji Count — zwraca liczbę wierszy w tabeli First — zwraca pierwszy wynik spełniający dany warunek Last — zwraca ostatni wynik spełniający dany warunek GroupBy – grupuje wyniki zapytań.
95
Microsoft ADO.NET Entity Framework (EF) to
biblioteka i zestaw narzędzi ORM (ang. Object Relational Mapping) do mapowania lub odwzorowywania danych z tabel w bazie danych na obiekty w aplikacji. Dzięki EF w aplikacji pracuje się z obiektami, które są automatycznie tłumaczone na zapytania zrozumiałe dla wskazanego do współpracy źródła danych. EF korzysta z technologii LINQ to Entities i pozwala na wygodną realizację operacji CRUD (create, read, update, delete)
96
public, private, protected, internal, protected internal
public: - powszechny dostęp - klasy i składowe private: -tylko w środku klasy - tylko składowe protected - w środku klasy i w klasie dziedziczącej - tylko składowe internal - w środku klasy, klasy dziedziczące i inne klasy w tym samym zestawie dotnet (ale tylko dla pól) - klasy i składowe protected internal - w środku klasy, klasy dziedziczące, klasy w tym samym zestawie dotnet i klasy dziedziczące w innym zestawie dotnet -tylko składowe
97
klasa generyczna jak deklarować? ograniczenia i jak je nakładać
class Klasa where T : struct - tylko typy wartościowe class Klasa where T: class(?) - tylko typy referencyjne, znak zapytania oznacza możliwość nulla class Klasa where T: notnull - blokuje możliwość przyjęcia nulla class Klasa where T: default - domyślne ograniczenia class Klasa where T: unmanaged - typy wartościowe i wskaźniki class Klasa where T: new() - musi mieć konstruktor bezparametrowy, musi być ostatni class Klasa where T: (?) - musi być/dziedziczyć po klasie lub być/implementować interfejs class Klasa where T: U - musi być typu U lub być pochodną typu U
98
porównanie rzutowania niejawne vs jawne vs referencyjne vs as
niejawne kiedy można przepisać dane bezstratnie np. int na long int albo z klasy pochodnej na bazową jawne kiedy można stracić dane np. double na int ,z bazowej na pochodną w przypadku rzutowania obiektów referencyjnych jawnie: Obj O1= (Obj)O2; // jeśli O2 nie jest typu Obj to wyjątek w przypadku użycia as: Obj O1 = O2 as Obj; // zostanie przypisany null jeśli O2 nie jest typu Obj tylko referencje