Order Czy wiesz, że mam na tym blog kurs Funkcyjnego programowania w C#. Dawno go nie odświeżałem, a wraz z pojawieniem się C# 9.0 myślę, że warto robi wpisy, które potrafią przełożyć filozofię funkcyjnego programowania na C#.  A sam C# tak jak przewidziałem na początku tego kursu będzie się zbliżał do trendów funkcyjnego progrowania i brał pomysły z F#.

Dzisiaj po wielkim powrocie omówimy Funkcje wyższego rzędu (Higher-order function). Jak wpiszesz "funkcje wyższego rzędu" do Google to zgłoszą Ci języki jak : Python, JavaScript. A jak to ma wyglądać w C#.

Funkcje wyższego rzędu są filarem funkcyjnego programowania.  Są to funkcje, które biorą albo inne funkcje jako parametry, albo zwracają nowe funkcję, które mogą być tworzone dynamicznie.

Tree Co prawda kiedyś dawno temu (w 2011 roku) zrobiłem wpis z implementacją drzewa binarnego. Znając jednak siebie z 2011 roku nie zaszkodzi zrobić takie szybkie przypomnieje i użyć wzorca iterator.

Zaczynamy od tworzenia gałęzi i liści drzewa binarnego. Każda gałąź ma wartość  i może, ale nie musi mieć następne gałęzi.

W konstruktorze przekazuje dalsze instancje tej samej klasy. Co oznacza, że możemy stworzyć prawdziwy łańcuch łączący te klasy, a raczej drzewo.

By Properties Iterator mówiąc krótko jest to obiekt, który przemieszcza się po strukturze obiektu. Iterator zazwyczaj ma referencję do obecnego obiektu, do którego ma dostęp i posiada także metodę by przejść do następnego elementu.

 Mam także iteracje dwukierunkowe, które pozwalają ci także iść w przeciwną stronę.

W .NET mam już sposób na implementację tego wzorca . Jest nim interfejs IEnumerator<T> . Posiada on następujące metody:

  • Current : referuję się do obecnego obiektu w tej pozycji
  • MoveNext() : pozwala Ci przesunąć się do elementu następnego w tej kolekcji. Jeżeli operacja się powiodła otrzymujemy wartość true, jeśli nie to false
  • Reset() resetuje do pozycji startowej

MachnineWzór.13 Nasze zachowanie jest sterowane przez nasz stan. Jeżeli nie wyspałeś się dobrze to twoje zachowanie zapewne się zmieni. Jeżeli wypiłeś dużo alkoholu to nie będziesz prowadził samochodu.  Stany więc decydują o tym co możesz i czego nie możesz zrobić.

Możesz oczywiście przejść z jednego stanu w drugi. Energetyk/Kawa może być takim wyzwalaczem, który zmienia twój stan.  Poranne ćwiczenia mogę Cię też bardziej rozbudzić.

Wzorzec projektowy State jest bardzo prosty. Stan kontroluje zachowania, a sam stan może zostać zmieniony.  Jak jednak ten stan zobrazować. Możemy to zrobić na dwa sposoby:

  • Stany są klasami z zachowaniami i te zachowania powodują zmianę z jednego stanu na drugi
  • Stany i przejścia są typami wyliczeniowymi. Mam specjalny oddzielny komponent, który wykonuje te przemianę stanu.

Oba te rozwiązania są właściwe. Drugi jest najbardziej popularny i kto wie być może już go użyłeś w swojej pracy. Pierwszy wymaga stworzenia wielu klas więc wydaje się on bardziej skomplikowany. Zauważ, że o ile wzorce projektowe mogą wydawać się cool czasami wygrywa rozwiązanie, które jest bardziej przejrzyste niż bardziej złożone. W końcu inni programiści muszą zrozumieć co chciałeś osiągnąć w kodzie

IObservableWzór.12 Mówiąc o wzorcu projektowym Observer warto także wspomnieć o tym, że w najnowszym .NET-cię mamy dwa ciekawe interfejsy generyczne : IObserver<T> i IObservable<T>. Te dwa interfejsy miały swoją premierę z biblioteką Reactive Extensions (Rx)

Ich celem było obsłużyć strumień reaktywnych informacji. 

Zobaczmy co interfejs IObservable<T> w ogóle robi.  Jaki jest on mechanizm? Do podpinania się do zdarzeń używamy operatora += . W tym interfejsie będziemy używać metody Subscribe() . Ta metoda bierze za parametr tylko interfejs IObserver<T>

Wszystko to jest interfejsem więc w przeciwieństwie do delegat i zdarzeń nie mamy tutaj określonego mechanizmu działania. Możemy z tymi interfejsami zrobić co chcemy

A co z odpinanie się od obserwacji, czyli od subskrypcją. Idea ta jest wpierana przez interfejsy Metoda Subscribe() zwraca obiekt interfejsu  IDisposable. Będzie to token, który metodę Dispose() odłączy się obserwacji obiektu observable.

EventWzór.11 Wzorzec projektowy Obserwator polega na tym,że jeden komponent informuje drugi, że coś się wydarzyło. Ten wzorzec jest używany wszędzie. W aplikacjach WPF i Windows Forms, jak i ASP.NET Web Forms i wszelkiej formie UI w platformie .NET mamy system zdarzeniowy. Ten system do program wysyła obiekty określający jakie zmiany zaszły przy interakcji z użytkownikiem.

Wzorzec Obserwator jest popularny i potrzebnym wzorcem w wielu miejscach w aplikacji nawet bez twojego kodu. Nic dziwnego, że twórcy C# postanowili zaszyć ten wzorzec do języka w postaci słowa kluczowego event 

Baby it's 8C# 8.0 przyniósł ze sobą wielkie zmiany. Niektóre z nich nie są zmianami kosmetycznymi i wywracają pewne pytania rekrutacyjne na Juniora C# na opak. Dobra wiadomość jest taka, że .NET Core 3.1 i .NET Standard 2.1 korzysta już domyślnie z C# 8.0 i nie trzeba już dodawać dziwnych wpisów preview.

W innym wpisie omówiłem już obsługę wartości Null w typach referecyjnych więc nie będę robił tego ponownie.  

Zobaczmy co innego przyniósł ze sobą C# 8.0.

TemplateWzór.10 Wzorzec projektowy Strategy i Template Method są podobne do siebie.  Jakie jednak są różnice . Wzorzec projektowy Strategy używa interfejsów i kompozycji do określenia zachowania algorytmu. 

Natomiast Template Method używa dziedziczenia . Klasa ustala szkielet algorytmu i jego kolejności natomiast implementacja poszczególnych kroków jest w zupełnie innym miejscu. Tym zajmą się klasy, które będą dziedziczyć po tej klasie szablonu

Istnieje mnóstwo przykładów tego wzorca. Często jest on reprezentowany przez artykuły jedzenia. Przykładowo masz tutaj szablon robienia naleśnika.

How to?Wzór.9 Mam więc listę napisów (Stefan,Jarek,Bajek) i chciałbyś je wyświetlić w specyficzny sposób. Możesz to zrobić po przecinku : (Stefan,Jarek,Bajek).

A może wyświetlić je po kropce : (Stefan.Jarek.Bajek)

A może wyświetlić je korzystają z elementu <ul><li> w HTML

  • Stefan
  • Jarek
  • Bajek

Każdy z tych formatów wymaga swojej logiki przetłumaczenia listy napisów na odpowiedni wynik.

Można by powiedzieć, że strategii.

Co, jeśli bym chciał wybierać tę strategię w trakcie działania programu? Zobaczmy jak wzorzec projektowy strategi działa.

SaveStateWzór.8 Używając wzorca projektowego Command, zapisywaliśmy akcje, które wykonywaliśmy w systemie i dzięki temu mogliśmy później te akcje cofać. 

Istnieje wzorzec projektowy, który też spełnia tę funkcję. Wzorzec Memento przechowuje stan systemu w dedykowanym obiekcie tylko do odczytu.

Ten token będzie użyty do przywrócenia systemu

ConnectingWzór.7 Większa część kodu, który piszemy, ma różne komponenty (klasy), które gadają ze sobą poprzez bezpośrednią referencję. Jednakże zdarzają sytuację, w których chciałbyś ,aby obiekty nie były świadome swojej egzystencji. 

Może chciałbyś, aby obiekty były świadome siebie, ale nie chcesz przekazywać za każdym razem referencyjni do nich

W końcu za każdym razem, gdy wysyłasz referencje obiektu, to przedłużasz jego życie w pamięci.

Mediator jest wzorce projektowym, który ma ułatwić komunikację pomiędzy obiektami, które fachowo nazywam kompomentami 

Mediator ma dostęp do każdego komponenty . Oznacza to, że powinien być on albo publiczny polem statycznym, albo singletonem, który jest wstrzykiwany do każdego komponentu, który go potrzebuje.

Ask meWzór.6 Powiedzmy, że chcesz przypisać wartość do zmiennej. Wystarczy do tego prosty kod jak : a = 4

Zmienna została zmieniona, jednak nie ma żadnej historii, aby zapisać, że takie zdarzenie nastąpiło. Nikt nam przecież nie może dać poprzedniej wartości tej zmiennej. Nie możemy przecież zapisać i serializować faktu o zmiany wartości. Czyż nie?

Co, jeśli chciałbyś cofnąć swoje działanie przypisania zmiennej. 

No cóż, skoro nie masz historii, nie masz informacji o poprzedniej wartości to zrobienie takiej operacji jest niemożliwe

Wzorzec projektowy "Command" stawia sobie ten właśnie cel. Zamiast działać na obiektach bezpośrednio, co by było, gdybyśmy mogli wysłać, im polecenia i instrukcje co trzeba zrobić.

Klasa reprezentująca tę polecenie będzie opisem tego, co trzeba zrobić i jak.

NullWzór.5 W pewnym wpisie omówiłem, że niektórzy architekci nie lubią wartość NULL, która występuję we wszystkich typach referencyjnych. Co, jeśli chciałbyś się tego pozbyć i zapomnieć o tym, jak C# 8 próbuje rozwiązać ten problem

No cóż, wtedy korzystasz ze wzoru projektowego Null Object

Event BrokerWzór.4 Poprzedni przykład wzorca  jest trochę sztuczny. W prawdziwym świecie będziesz chciał, aby stwory, zyskiwały lub traciły bonusy w dowolny sposób. To jest coś, czego nie zrobisz, mając listę jednokierunkową czy łańcuch zobowiązań

Nie chciałbyś permanentnie zmieniać dane swojego stwora. Chcesz, aby ta zmiana działa w tymczasowo i tylko wtedy gdy jest ona potrzebna.

Potrzebny nam będzie scentralizowany komponent. Będzie on trzymał listę wszystkich modyfikatorów dostępnych w grze. Będziemy wyszukiwać te modyfikatory i dodawać je do stworów mając pewność, że wszystko odbywa się w dobrej kolejności.

Ten komponent nazywa się Event Broker. Co ciekawe jest on połączeniem kilku wzorców projektów jak Mediator, Observer, Command 

Chain of ItemsWzór.3 Pomyśl, że pracujesz nad daną aplikacją i okazuje się, że coś zostało źle zaprogramowane. Kto jest za to odpowiedzialny? Ty? Twój szef, który dał Ci zadanie? A może analityk aplikacji? A może osoba biznesową źle zrozumiała proces, który próbujesz zaprogramować

To jest właśnie łańcuch odpowiedzialności. Dodatkowo jest to także wzorzec projektowy. Jego zadaniem jest wywołać elementy systemu jeden po drugim.

Implementacja tej filozofii wydaje się prosta. Potrzebna Ci jest lista jednokierunkowa oraz klasa abstrakcyjna, która posłuży za szablon do działania

SingletonWzór.2 Wzorzec projektowy Singleton urósł na podstawie prostego pomysłu : Co jeśli chcesz mieć instancję jednego pewnego komponentu w swojej aplikacji, bez względu na to ile razy go utworzysz  przy pomocy konstruktora. 

Przykładowo masz klasę, która ładuje pewne dane z bazy tylko raz w cyklu życia w aplikacji. Ta klasa jeszcze posiada tylko pola do odczytu.

Taka klasa jest dobrym kandydatem na  wzorzec projektowy Singleton. Po co obciążać pamięć swojej aplikacji obiektami, które mają dokładnie te same dane.

Wzorzec projektowy Singleton można zaimplementować w C# na kilka sposobów

C# i NULL NullReferenceException. Ile razy w swojej karierze widziałeś ten błąd. Wielu programistów i geniuszy architektury programowania od dawna się zastanawia, że może wartość NULL w typach referencyjnych to duży problem.

W C# nie ma wielokrotnego dziedziczenia. Null jest tym wyjątkiem, bo technicznie dziedziczny on po wszystkich wartościach referencyjnych. Brzmi to, jak łamanie jakieś zasady projektowej

Niektórzy mają śmiałość mówić, że jest to problem wart miliardy dolarów

Wyjaśnijmy ich punkt widzenia

PytaniaPyt NR.1 Cześć! Dzisiaj postanowiłem napisać coś na temat rozmów kwalifikacyjnych. Ludzie prosili mnie o to, od kiedy napisałem wpis na temat szukania pracy w Warszawie po raz pierwszy. Ciekawa lektura dla tych, którzy skończyli studia inżynierskie i szukają pracy w wielkim mieście.

Przejdźmy jednak do pytań. Bo jakie pytania możesz dostać szukając po raz pierwszy pracy jako programista. Jeśli więc szykujesz się rozmowę mam nadzieję, że to ci pomoże.

Pytania są banalne. Postanowiłem na razie opisać te najbardziej oczywiste.

PłuapkiPyt NR.1 Pamiętam swoje pierwsze przygody z językiem C# i swoje błędy. Pamiętam jak z kolegą pisaliśmy algorytm ewolucyjny i zastanawialiśmy się, dlaczego mamy przepełnienie stosu. Zdecydowanie wtedy obaj o czymś zapomnieliśmy.  Często zdarzało mi się zapomnieć, że istnieją inne kolekcję w C# niż tablice. Korzystałem więc z tablic, bo przy nich czułem się bezpiecznie i to one były najczęściej używane na zajęciach.

Jak widać nie byłem takim zdolnym programistą w czasach studenckich. Postanowiłem więc zrobić listę pospolitych pomyłek nowicjusza.

Dynamic C# 4.0 przedstawił nowy typ “dynamic”. Istnieje on już od pewnego czasu, ale pytanie, dlaczego nie jest tak często używany? Odpowiedź jest oczywiście prosta, ponieważ słowo kluczowe dynamic przydaje się w wybiórczych przykładach.

Przykładowo typ dynamic jest używany do wiązania danych na samym dnie C#. Kiedyś te operacje wykonywały się na napisach bądź obiekcie System.Object, teraz to wszystko wędruje do dynamicznej zmiennej, która może określać wszystko.

Dynamic też przyda się bardzo przy operacjach z bibliotekami COM. COM w końcu to system, który jest w połowie dynamiczny. Wiele metod COM zwraca więc dynamiczny obiekt. Przed C# 4.0 zostawał zwracany obiekt, co trochę komplikowało sprawę. Trzeba było wtedy rzutować i zgadywać czym ten obiekt jest.

W sumie tak samo jest z typem dynamic, ale jeśli mam pewność, że wszystkie obiekty umieszczone w tym typie zawsze będą miały tę jedną wspólną właściwość, to wszystko jest w porządku.  Właściwie typ mnie nie interesuje bardziej zakładam, że dana właściwość lub pole pojawią się bez względu na wszystko. 

Jest Moc Nadszedł czas, aby poszerzyć swoją wiedzę na temat C#. Istnieje kilka ciekawych funkcjonalności, które mogą ci ułatwić pracę z kodem

Raz na jakiś czas warto odnowić swoją wiedzę.

Currying howCzęść NR.8 W poprzednim wpisie widzieliśmy przykłady jak Currying działa. Przykłady te były opisane na zmiennych zadeklarowanych, albo jako anonimowe metody, albo jako wyrażenia lambda. Zmieniliśmy te funkcje do postaci łańcucha wywołań funkcji, które przyjmują zawsze tylko jeden parametr.

Jak to jednak by wyglądało w C# , w kontekście klas. Jak mieć metodę Currying w stylu języków funkcjonalnych.

Jakie ja napotkałem problemy pisząc ten prosty przykład edukacyjny.

CurryingCzęść NR.7 Gdzie leży serce programowania funkcjonalnego. Oczywiście w jego funkcjach, które są składową większego algorytmu. Haskell Curry był matematykiem i to od niego wywodzi się termin Currying, jak i cały język programowania Haskell.

Currying sprawia, że jesteśmy w stanie zobaczyć wszystkie funkcje jako funkcje jednoparametrowe bez względu na to, ile parametrów tak naprawdę potrzebujemy do wyliczeń i działania.

Jak to jest możliwe? Przecież gdzieś te parametry muszą być? Jest to jednak prostsze niż się wydaje.

Otwiera nas to na dzielenie aplikacji  na mniejsze elementy. Jest to jedna z głównych esencji każdego języka funkcjonalnego.  Jak to wygląda w C#, który do końca nie jest językiem funkcjonalnym.

RekurecjaCzęść NR.9 W funkcjonalnych językach programowania rekurencja jest narzędziem z dużą tradycją. Wiele oryginalnych języków funkcjonalnych nie miało konstrukcji pętli. W takich wypadkach była używana rekurencja.

Obecnie wiele języków funkcjonalnych ma definicję pętli w swojej składni.

Nie zmienia to jednak faktu, że rekurencja wciąż jest używana przez wielu programistów.

Future C# Czy warto uczyć się C#? Oczywiście język dojrzał i – co więcej – czeka na niego świetlana przyszłość.

C# ma już 16 lat. Przy pomocy C# możemy tworzyć strony internetowe, aplikacje na Androida, iOS i aplikacje na Windows 10. Mam też aplikacje na systemy Windows jak Windows Forms i WPF. Do tego stosu też można dodać usługi Windows, które działają w tle systemu.

Na koniec możemy wspomnieć o aplikacjach na systemy Office i SharpPoint.

CreateCzęść NR.6 Pomówmy o wyrażeniach drzewiastych raz jeszcze. Wyrażenia drzewiaste są naprawdę potężnym narzędziem, ponieważ traktują kod jak dane. W poprzednim wpisie przyjrzeliśmy się jak wyrażenia drzewiaste są zbudowane i jak je wykorzystać.

W tym wpisie skoncentrujemy się na tworzeniu wyrażeń, jak i ich zmianie.

Tematyka ta jest dosyć obszerna dlatego postanowiłem przygotować tylko parę ciekawych przykładów, które wykazują pewną użyteczność tworzenia dynamicznych wyrażeń.

DekoratorWzór.1 Dekorator. Śmiało mogę powiedzieć, że jest to jeden z najważniejszych wzorców projektowych. Można powiedzieć, że jest on prawie częścią każdego systemu, ponieważ nie ma co ukrywać, jest on pożyteczny i użyteczny nawet do dzisiaj.

Dekorator pozwala dodać istniejącej klasie nowe zachowanie.  Nie zmienia on jednak działanie klasy podstawowej. Oznacza to, że spełnia następujące zasady S.O.L.I.D:

 

  • pojedynczej odpowiedzialności
  • zasady otwartej-zamkniętej

Dekorator, jak i jego klasa bazowa mają tylko jedno zadanie. Dekorator pozwala nawet rozbić zachowanie klas, jeśli widzisz, że te rozbicie jest potrzebne. W tym przykładzie to pokażę.

Chciałbyś się zapewne nauczyć tego wzorca. Zamiast tego przyjrzymy się przykładzie Pizzy. Kod jest do pobranie na końcu artykułu.

Wyobraź sobie, że masz następujący zestaw klas.

Tags Ostatnio ulepszając swojego bloga miałem proste zadanie. Chciałem przy pomocy swoich własnych znaczników modyfikować tekst w postach.

Nie jest to nic odkrywczego. Blog WordPress ma dużo swoich własny znaczników i tagów, które mają ułatwić ci wstawanie n.p filmików z YouTube albo TED-a.

Ten blog jest napisany w C# przez mnie, a to znaczy, że jeśli czegoś w nim nie ma to znaczy, że muszę to napisać.

ThreadingCzęść NR.5 Jak można wykorzystać programowanie aspektowe w pożyteczny sposób?

Interceptory mogą się przydać przy tworzeniu nowych wątków. Pisząc aplikację w WPF lub Windows Forms łatwo zauważyć tę sytuację. Podczas wykonywania jakiejś długiej czynności w kodzie możesz zauważyć, że cały wątek UI został zatrzymany. Oznacza to, że nie możesz ruszyć okna, nie możesz skrolować okna i nie możesz na nic klikać, bo cały wątek odpowiedzialny za to jest zajęty.

C# 7.0 Na konferencji Build 2016, Microsoft wypuścił pierwszy publiczny wgląd do nowego Visual Studio 15. Po co go zainstalować? Warto go mieć by zobaczyć, co obecnie można zrobić w kolejnej iteracji języka C#. Jest to siódma iteracja C#. Pojawiło się w niej wiele ciekawych sztuczek.

Instalacja Preview Visual Studio 15 wydaje się mało inwazyjna na cały ekosystem programistyczny w moim komputerze. Wydaje się, że w każdej chwili mogę odinstalować ten edytor bez niszczenia czegokolwiek w swoim systemie operacyjnym.

#6 Kod to...Część NR.5

Kiedyś szczytem wszystkich wynalazków stworzonych przez programistyczne języki funkcjonalne była możliwość wykonania funkcji, gdy ona jest w formie napisu string.

Ten napis można było zmieniać i później go wywołać jak zwyczajny kod.

Inaczej mówiąc “eval” .

Wiele języków programowania wspiera operację “eval” czyli możliwość wywołania funkcji w danym języku, gdy dynamicznie tworzymy wyrażenie tej własnej funkcji.

Najprostszy eval jak powiedzieliśmy wcześniej wymaga do operacji zwykłego napisu string. Języki, które to wspierają pozwalają na wywołanie takiego kodu. Oto przykładowy kod JavaScript.

ClousersCzęść NR.4

Aby język programowania mógł działać z Funkcjami wyższego rzędu musi rozwiązać problem z zasięgiem zmiennych. O co chodzi?

Funkcja wyższego rzędu jest to funkcja, która przyjmuje jako parametry kolejne funkcje. Co się jednak dzieje z parametrami zaszytymi w wewnętrznych parametrach funkcji?

Kiedy funkcje są przekazywane jako parametry, zmienne, wartości zwracane - wtedy kompilator używa domknięcia, aby rozszerzyć zasięg zmiennych tak, by były one dostępne wtedy, gdy są potrzebne.

W tym wpisie spojrzymy na problem z zasięgiem zmiennych i na domknięcia, ale najpierw…zobaczymy jak w C# dynamicznie tworzy się funkcję.

ComparisonSmak NR.4

Podobnie jak delegaty: Predicate, Converter - delegata Comparsion istnieje głównie po to, by dać możliwość kolekcjom Array i List<T> możliwość sortowania.

Obecnie jednak nie korzystam z metody Sort, tylko z metody LINQ OrderBy.

Używanie delegaty tak, jak w poprzednich przypadkach nie ma sensu. Sama delegata istnieje dla metod np. Sort.

PrzeciążanieCzęść NR.19

Witaj w przedostatnim  wpisie z tego cyklu. Poza wielkim podsumowaniem czego w Javie nie ma, a jest w C# wypadałoby jeszcze coś powiedzieć o przeciążaniu metod w C# i w Javie, ponieważ różnice są.

Zacznijmy od C#.

Elementy klasy pochodnej mogą redefiniować metodę klasy bazowej. W klasie pochodnej tworzymy metodę o tej samej nazwie i liście parametrów, co metoda w klasie pochodnej.

Metoda ta będzie miała nowe zachowanie. Inne niż metoda z klasy bazowej.

ConstrainsCzęść NR.18

Generics, Typy generyczne referują się do typów, których definicja metody, klasy i interfejs operują zależnie od tego, co podasz do niego.

Typy generyczne mają wiele zalet jedną z nich jest wykrywanie ich działania już na poziomie pisania kodu oraz to, że pozwalają na uniknięcie konwersji typów.

 

GenericsCzęść NR.17

Generics, Typy generyczne referują się do definicji metody, klasy i interfejsów, które operują zależnie od tego, co podasz jako parametr generyczny.

Typy generyczne mają wiele zalet jedną z nich jest wykrywanie ich działania już na poziomie pisania kodu. Dzięki nim też możemy uniknąć konwersji typów.

Try-CatchCzęść NR.16

Przechwytywanie wyjątków pozwala programistom rozwiązać problem związany z tym, że w każdej aplikacji może wystąpić nieprzywidziana sytuacja.

Przykładowo jeśli chcesz otworzyć plik używając FileReader z Javy, albo StreamReader z C#, to istnieje kilka sytuacji, które mogą wywołać błąd działania, czyli wyjątek. Przykładowo plik może nie istnieć.

ConverterSmak NR.3Przerobiliśmy 3 z 5 szablonów gotowych generycznych delegat. Zostały nam jeszcze dwa. A w tym wpisie opiszę delegatę Converter.

Nie ma w niej niczego specjalnego. Jest to kolejna delegata, która istnieje z powodu starego kodu .NET 2.0 sprzed LINQ.

Celem tej delegaty jest przekonwertowanie jednego obiektu w drugi. Od razu rodzi się pytanie po co używać do tego oddzielnej delegaty gdy mamy delegatę Func.

PredicateSmak NR.2

Predicate to gotowy szablon delegaty/wskaźnika do metody.

Metoda referowana w Predicate musi zwrócić wartość true/false.

Spełnia ona inną role niż klasyczne szablony delegat jak “Action” i “Func”, które opisałem wcześniej. Pytania brzmi na czym polega różnica.

Możesz sobie zadać pytanie dlaczego w ogóle z nich korzystać. Dla czytelności systemu może łatwiej jest użyć delegaty Func<T,Bool>. Dlaczego Predicate w ogóle istnieje?

EnumCzęść NR.15

Typ wyliczeniowy jest to typ, który zawiera określoną liczbę nazwanych stałych. Aby utworzyć typ wyliczeniowy wystarczy użyć słowa kluczowego “enum” zamiast “class”.

Wewnątrz nawiasów klamrowych po przecinku definiujemy listę stałych elementów. Zasady poziomu dostępu typu wyliczeniowego są takie same jak zasady dla klasy.

W Javie stałe wartości enum są pisane z dużych liter.

AbstrakcjaCzęść NR.14

Klasa abstrakcyjna dostarcza implementacje innym klasom. Klasa abstrakcyjna jest więc taką podstawką dla pozostałych klas.

Klasa abstrakcyjna może zawierać zestaw kompletnych metod, które będzie posiadać klasa pochodna. Klasa abstrakcyjna może też mieć zestaw abstrakcyjnych metod, które nie są zdefiniowane w swoim działaniu. Podobnie do interfejsów, w takich metodach istnieje tylko sygnatura metod. Nie ma w nich ciała.

C# Java

InterfejsyCzęść NR.13

Interfejs to typ, którego zadaniem jest rozłączenie implementacji działania od definicji parametrów wyjścia.wejścia.

Jest to specyficzny kontrakt, który jest implementowany przez klasy. Kontrakt ten zawiera tylko informacje o co dana metoda ma się zwrócić i co ma ona przyjąć. Definicja działania jest już określona w klasie.

StałeCzęść NR.12

Zmienna w C# określona słowem kluczowym const staje się stałą, której zawartość jest na zawsze zawarta w bibliotece, w trakcie kompilacji. Ta wartość nie może zostać zmieniona w trakcie działania programu.

Próba przypisania jakiekolwiek wartości do stałej będzie skutkować błędem.

Stałe muszą znajdować się w klasie jako pole lub w lokalnym bloku kodu .

Poziom.DCzęść NR.11

Poziomy dostępu deklarują na jakim poziomie dany element klasy bądź sama klasa jest widoczna.

W Javie mamy 4 typy dostępu. Są one następujące: public, protected, private i private na poziomie paczki.

Ten ostatni poziom nie może być jawnie zadeklarowany za pomocą słowa kluczowego.

Warto zaznaczyć, że poziom dostępu protected daje dostęp do wszystkich klas w danej paczce, nawet jeśli one nie dziedziczą po tej klasie.

DziedziczenieCzęść NR.10

Dziedziczenie pozwala klasie na uzyskanie elementów (pól, metody) innej klasy. W przykładzie poniżej klasa kwadrat dziedziczy po klasie prostokąt.

Prostokąt staje się klasą bazową Kwadratu.

W dodatku wszystkie elementy klasy Prostokąt, jeśli są one dostępne stają się elementami klasy Kwadrat. Wyjątkami są konstruktor i w przypadku C# destruktory.

StaticCzęść NR.9Słowo kluczowe “static” jest używane do tworzenia pól i metod do których dostęp nie wymaga utworzenia instancji klasy.

Statyczne elementy wewnątrz klasy należą do samej klasy. Nie statyczne elementy są kojarzone z każdą kopią obiektu.

Oznacza to, że każde statyczne elementy nie mogą używać elementów powiązanych z instancją/obiektem danej klasy. Na poziomie statycznych elementów instancja klasy i jej elementy nie istnieją.

Z drugiej strony metody niestatyczne mogą korzystać z statycznych metod i pól.

KlasaCzęść NR.8

Klasa jest to szablon używany do tworzenia obiektów. Klasy składają się głównie z dwóch członów: pól i metod. (C# ma tego więcej)

Pola są zmiennymi, które trzymają stan obiektu. Metody definiują, co obiekt potrafi.

Poniżej znajduje się klasa opisująca kwadrat. Ma ona dwa pola x i y oraz metodę GetArea().

#4 InterceCzęść NR.4

W poprzednim wpisie omówiłem, czym jest intercepcja w programowaniu. Chociaż jak zajrzysz do Googli, to możesz zobaczyć, że słowo to często jest używane w footballu amerykańskim.

Poprzednim razem skorzystaliśmy z Castle.Windsor i DynamicProxy.

Teraz zrobię to samo tylko przy użyciu PostSharpa. Wpis będzie krótki, gdyż omówienie techniczne zostało zrobione wcześniej.

Aby użyć PostSharpa musimy stworzyć klasę aspektową.

#3 CastleCzęść NR.3

W poprzednim wpisie pokazałem prosty przykład AOP z PostSharpem.

Teraz pokażę wam podobny prosty przykład AOP, ale z Interceptorami z Castle.Windosor.

Różnica tej techniki z PostSharpem jest duża.

Kontener wstrzykiwania zależności Castle będzie dodawał aspekty w trakcie wykonywania programu. PostSharp robił to poprzez dodatkowy proces kompilacyjny.

Warto też zaznaczyć, że ten przykład będzie się różnił od poprzedniego przykładu. Dlaczego?

Muszę wyjaśnić czym jest intercepcja metody

#2 PostSharpCzęść NR.2

Czas na proste demo AOP przy użyciu PostSharp i IL Code Weaving.

W poprzednim wpisie omówiłem na czym polega AOP. Jeśli jeszcze wszystkiego nie rozumiesz, to spokojnie dopiero patrząc na konkretne przykłady, sprawa z AOP staje się jasna jak żarówka.

Projekt Demo zaczynamy od utworzenia nowego projektu w Visual Studio.  Demo będzie proste, dlatego wystarczy nam aplikacja konsolowa.

AOPCzęść NR.1

Programowanie aspektowe – to brzmi skomplikowanie, ale w rzeczywistości tak nie jest. Programowanie aspektowe - w skrócie AOP, pomaga spędzić mniej czasu na kopiowaniu i wklejaniu tego samego kodu.

Te powtarzające fragmenty kodu fachowo nazywają się “boilerplate”.

Redukując powtarzalność kodu możesz poświęcić więcej czasu na ważniejsze części projektu i dodać do niego, i do innych projektów wartość dodaną.

AOP w .NET może zostać uzyskane na wiele sposobów. Najpopularniejszymi sposobami są techniki związane z:

  • Castle Windsor i Intercepotrami
  • PostSharpem i Aspektach

#3 LambdaCzęść NR.3

Nie wszystkie funkcje są tak ważne, że muszą mieć nazwę. C# wspiera anonimowe funkcje od wersji 2.0. A od wersji 3.0 anonimowe funkcje pojawiły się w lepszej wersji. W wersji wyrażeń lambda.

Te funkcje nie żyją na poziomie klas i dlatego nie mają nazw. Referencje do takich funkcji zazwyczaj przetrzymuje się w postaci zmiennych typu danej delegaty.

Istnieją pewne ograniczenia dotyczące tego, gdzie anonimowe funkcje mogą się znajdować i jakie mają być.

Przykładowo nie mogą one być generyczne.

#2 DelegateCzęść NR.2

C# jest językiem obiektowym. C# nie pozwala na użycie “funkcji” poza klasami. Jest to wielka różnica w porównaniu z C++ - pierwszym językiem programowania zorientowanym obiektowo. C++ pozwala na pojawianie się funkcji poza klasami ze względu na wsteczną kompatybilność z językiem C.

Można się kłócić, że skoro C# ma klasy statyczne z statycznymi metodami to programowanie imperatywne istnieje, ale jest ono ukryte za obiektową terminologią.

Funkcje w C# mogą istnieć tylko wewnątrz klas i co ważniejsze nie nazywamy je funkcjami, tylko metodami. Metody w C# zawsze muszą coś zwracać. Na szczęście ta zasada jest omijana poprzez typ void. Dzięki temu w metodzie nie musimy używać słowa kluczowego return.

Co to jest?Część NR.1Programowanie funkcyjne istnieje od bardzo długiego czasu. Język programowania LISP w 1958 roku postawił punkt startowy w programowaniu funkcjonalnym.  Z drugiej strony LISP już wtedy bazował na koncepcjach, które istniały. Pierwsze kroki w kierunku programowania funkcjonalnego  można datować na lata 1930-1940. Wtedy Alonzo Vhruch opracował lambda Calcus.

http://en.wikipedia.org/wiki/Lambda_calculus*

Co to jest programowanie Funkcyjne

Programowanie funkcje jest kolejnym paradygmatem programowania, który występuje w wielu językach programowania. Jak sama nazwa wskazuje koncentruje się na funkcjach.

Dla niektórych programistów programowanie funkcyjne wydaje się być naturalne. Funkcyjne programowanie według nich bardziej koncentruje się na problemie, który powinien być rozwiązany niż na poszczególnych krokach rozwiązania problemu.

ReWrite

W poprzednich wpisach pokazałem jak przy użyciu wyrażeń drzewiastych wyciągać kod.

Jak jednak kod ten zmienić.

Do spacerów po kodzie używaliśmy klas opartych na wzorcu “Vistor”. W tym wypadku podobne rozwiązanie jest zalecane.

Chociaż na siłę można zmieniać wyrażenie drzewiaste jakby to były pliki XML. Jest to jednak trudne i kod taki nie jest czytelny.

C#

Func ActionSmak NR.1

Dlaczego znowu piszę o delegatach. Otóż widzę, że wiele osób wchodzi na mojego bloga, by się dowiedzieć “co to jest i jak to działa”. W 2011 roku, na szybko napisałem pewien wpis, który swoim przykładem miał zobrazować zależności wynikające z mechanizmu delegaty. W wielkim skrócie wpis mijał się z celem.

Dlatego postanowiłem napisać kolejny wpis o delegatach bez żadnych udziwnień.

Postanowiłem też w tym wpisie poruszyć ważne zagadnienie, które jest reprezentowane przez gotowe delegaty jak “Action<T>” i Func<T,T>.

AddDocumentCzęść NR.6Rolsyn API umożliwia z poziomu C# na kompilowanie kodu. Roslyn także zawiera klasy, które potrafią odwzorowywać projekty w solucji tak w Visual Studio.

W poprzednim wpisie opisałem jak użyć Workspace API, ale pracując z tymi klasami zauważyłem, że wiele rzeczy po prostu nie działa.

Po pierwsze wiele rzeczy obecnie nie jest wspieranych w tym API mimo iż metody istnieją.

Sublime TextMasz już dosyć setki utworzonych aplikacji konsolowych w Visual Studio tylko po to by sprawdzić jak dana klasa lub kod działa?

ConsoleApp

Czy istnieje jakiś lepszy sposób na prototypowanie kodu? Czy istnieje jakiś lepszy sposób na pokazanie kodu demo?

A może do tego chciałbyś mieć w pełni interaktywne doświadczenie z kodem C#.

ScriptCS

Pojawienie się kompilatora Roslyn otworzyło wiele nowych ścieżek.

Jedną z tych ścieżek jest biblioteka ScriptCS.

Dzięki niej jest możliwe używanie C# jako języka skryptowego w konsoli. Dzięki niemu edytory takie jak Notepad++ mogą kompilować kod napisany w C#.

Co najważniejsze można użyć tej biblioteki do własnych celów.

WorkspaceCzęść NR.5

Czym jest Workspace API?

Co to jest Workspace?

Workspace reprezentuje solucje w Visual Studio. Klasy więc z tego api będą modelowały układ danej solucji.

Oczywiście rola tych klas nie kończy się tutaj. Przy użyciu tych klas możemy dodawać referencje do projektów i usuwać pliki.

SemanticCzęść NR.4

Znając już Syntax Tree API oraz API kompilacyjne powstaje pytanie, jak można uzyskać pewne semantyczne informacje na temat kodu, używając obu API.

Przykładowo chcę uzyskać informację, czy podane wyrażenie wewnątrz metody jest wyrażeniem stałym. Jeśli nim nie jest, to zapewne jest ono powiązane z działaniem specyficznej metody operacyjnej jak znak “dodawania”.

EmitCzęść NR.3

Wewnątrz kompilatora Roslyn oczywiście istnieją klasy, które na podstawie podanego kodu potrafią utworzyć biblioteki.

Są one znakomitą alternatywą dla System.Reflection.Emity  i CodeDOM.

Generowanie kodu jeszcze nie było takie łatwe.

Klasy kompilujące potrafią także bardzo szczegółowo poinformować użytkownika, dlaczego dany kod się nie skompilował.

Syntax TreeCzęść NR.2

W poprzednim wpisie omówiłem w skrócie kompilator Roslyn i to jakie problemy on rozwiązuje.

W poprzednim wpisie też napisaliśmy proste rozszerzenie do Visual Studio, które korzysta z kompilatora Roslyn.

Zanim jednak zaczniemy zabawę na całego z każdym API kompilatora Roslyn, trzeba zacząć od podstaw. Taką podstawą jest API Syntax Trees .