Słowo var zostało wprowadzone w .NET 3.5, prawdopodobnie ze względu na LINQ i anonimowe typy. Jedni programiści za wszelką cenę unikają tego słowa kluczowego a drudzy zapomnieli o typach i zawsze korzystają var bo w końcu to nowy feature… Nawet Resharper sugeruje aby zawsze używać var ponieważ skraca to składnie. Istnieje też spora trzecia grupa do której m.in. ja należę i postaram się pokazać kilka przykładów. Moja zasada jest prosta – używam var tylko jeśli w momencie deklaracji można wywnioskować typ...
Strona głównaUżytkownik
pzielinski | użytkownik
W kilku miejscach spotkałem się z błędną definicją CopyTo oraz Clone. W przeciwieństwie do niektórych opinii, obydwie metody wykonują shallow copy. Jak wiemy w c# mamy reference oraz value types. Podczas płytkiego kopiowania, typy value po prostu klonowane są bit po bicie. W przypadku typów referencyjnych, wyłącznie adres jest kopiowany, nie wartość. Zatem po skopiowaniu typu referencyjnego będziemy mieli dwa wskaźniki, wskazujące na te same dane. Przykład:SampleClass[] array =new SampleClass[] {sampleC...
Zgodnie z obietnicą dziś napiszę trochę więcej o rzutowaniu, wydajności oraz dobrych praktykach. Muszę przyznać, że w jednej kwestii miałem nieprawdziwe informacje (znalezione gdzieś na forum) których byłem pewien ponieważ napisałem prosty program sprawdzający wydajność – jak na końcu pokażę popełniłem błąd podczas mierzenia wydajności spowodowany kompilacją JIT. Na początku trochę przypomnienia: 1. Rzutowanie prefiksowe – najpopularniejszy typ znany np. z CPP. int value = (int)boxedValue; Można wyk...
Co powiedzie na taki fragment kodu?FileInfo fileInfo; if (sender is FileInfo) fileInfo = sender as FileInfo; Konstrukcja jest dość popularna i: - oczywiście skompiluje się, - jest bezpieczna na wartość NULL (tzn. nie wyrzuci wyjątku), - jeśli sender jest innego typu niż FileInfo, kod nie wyrzuci wyjątku. Co jest w końcu nie tak? Chodzi tutaj o good practice i nie wprowadzanie czytelnika kodu w błąd. Operator is sprawdza czy obiekt jest danego typu. Zatem w instrukcji IF wiemy już, że sender ...
Słowo kluczowe yield jest dość często wykorzystywane w c#. W przeciwieństwie do poprzednich konstrukcji, które opisywałem (np. volatile), nie trudno znaleźć zastosowanie praktycznie w projekcie. Zacznijmy może od razu od przykładu:foreach (int value in GetNumbers(5,7)) { MessageBox.Show(value.ToString()); } // ------------------private IEnumerable
Rozważmy, dwie zupełnie bezsensowne klasy:class TextInfo { publicstring Text { get; set; } } class NumberInfo { publicint Number { get; set; } } Następnie gdzieś w kodzie próbujemy dokonać konwersji:NumberInfo numberInfo =new NumberInfo {Number =43}; TextInfo textInfo1 = numberInfo; // konwersja niejawnaTextInfo textInfo2 = (TextInfo)numberInfo; // konwersja jawna Czy, którakolwiek przedstawiona konwersja zakończy się sukcesem?Oczywiście, że nie – skąd .NET ma wiedzieć jak należy zamienić je...
W ostatnich kilku postach przedstawiłem “egzotyczne” słowa kluczowe w c#. Wiele z nich, myślę, nie było znanych nawet bardziej zaawansowanym programistom. Z pewnością nie są one niezbędne do pisania aplikacji. Często nawet nie jest wskazane aby z nich korzystać, chyba, że naprawdę dokładnie przeanalizowaliśmy sytuację. Słowo zaprezentowane w dzisiejszym poście również zalicza się do tego zbioru. Myślę, że volatile może być znane programistom C++ ale w świecie c# jest dużo mniej popularne. Jeśli piszecie...
W programowaniu obiektowym użycie tak popularnej konstrukcji jak if-else jest często symptomem złej architektury. Załóżmy, że mamy metodę walidująca dostęp do danych np:privatebool Validate(string userName, string password, AuthType authType) { if(authType == AuthType.PlainPwd) { if(password == _user.Password) returntrue; } elseif(authType == AuthType.MD5) { if(Md5.Hash(password) == _user.Password) } elseif(authType == ....) // ITD... } Powyż...
Dziś następna porcja bardziej egzotycznych słów kluczowych w c#. Słowa unchecked oraz checked służą do kontrolowania czy nie nastąpił overflow podczas operacji arytmetycznych. Wszystkie niepoprawne operacje w klauzuli checked wywołają wyjątek overflow, ponieważ podczas wykonywania obliczeń sprawdzane jest czy wynik wciąż się mieści w zmiennej. Na przykład:checked { int i =0; while (true) i++; } Po pewnym czasie, gdy zmienna i przekroczy Interger.Max, zostanie wyrzucony wyjątek. .NET z...
Witam, co powiedziecie na taki kod?class Employee { public Employee() { Init(); } publicvirtualvoid Init() { } } class Manager : Employee { public Manager() { } publicoverridevoid Init() { } } Czy jest to dobry design? Jeśli ktoś programował w C++, na pewno nie zgodzi się na wywoływanie jakiejkolwiek metody wirtualnej w konstruktorze. W CPP zostałaby wywołana metoda Employee:Init zamiast Manager:Init ponieważ w momencie tworzenia Employee, obiekt Manager jes...
Dziś znowu zaprezentuję mało znane słowo kluczowe w języku c# – stackalloc. Najpierw jednak kilka słów przypomnienia na temat alokacji pamięci w .NET. Generalnie mamy dwa typy obiektów: reference type oraz value type. Typy referencyjne to klasy, z kolei value type to Enum, Integer, Float itp. Klasy alokowane są na stercie (heap), która zarządzana jest przez Garbage Collector. Value Type deklarowane są z kolei na zwykłym stosie. Wyjątkiem jest sytuacja w której value type jest składową reference type (...
Wielu z Was kojarzy zapewne konstrukcję unsafe do deklarowania stref niezarządzanych w których możemy np. wykorzystywać wskaźniki i inne mechanizmy znane z języków niezarządzanych. Słowo fixed wydaje mi się, że jest nieco mniej popularne. Wiemy, że w środowisku .NET, gdzie zasoby pamięci zarządzane są przez Garbage Collector, obiekty mogą zmieniać swój adres. W poprzednich postach (o GC) pisałem, że przy zwolnieniu obiektów, wszystkie pozostałe są szeregowane jeden po drugim, tak aby uniknąć problemów ...
W ostatnim poście obiecałem pokazać na przykładzie, że destruktory rzeczywiście mają negatywny wpływ na wydajność. Mamy prostą klasę:class MyClass { ~ MyClass() { // Jakis bezensowny kod np:for (int i =0; i <100*10000; i++) { var newinstance =new myclass(); } stopwatch.stop(); long duration = stopwatch.elapsedmilliseconds; przyjrzyjmy się teraz diagramowi przedstawiającemu rozkład obiektów względem generacji (clr profiler): na moim komputerze duration wyniósł 900. usuńmy destruk...
Jeśli miał ktoś do czynienia np. z CPP z pewnością kojarzy pojęcie destruktora. Jest to metoda, wywoływana w momencie zwalniania obiektu z pamięci (przeciwieństwo konstruktora). Zarówno w CPP jak w C#, nazwa destruktora stanowi ‘~’ plus nazwa klasy.
W poprzednim poście przedstawiłem zasadę działania generacji w GC. Dowiedzieliśmy się, że zwalnianie zasobów z generacji 0 jest bardzo szybkie z kolei z GEN 2 wolne. Healthy GC to reguła określająca optymalny (zdrowy) stan GC: gen0 : gen1 : gen2 => 100 : 10 : 1 W Internecie można również znaleźć nieco inne wartości ale ogólna zasada jest taka sama: GEN0 powinna zawierać dużo więcej obiektów niż GEN2. Jeśli obiekty nie są zwalniane, wtedy promowane są do generacji pierwszej i drugiej. Z poprzedniego po...
W poprzednim poście przedstawiłem ogólne zasady działania GC w zarządzanych językach. Dziś przyjrzymy się bardziej na konstrukcję rozwiązania Microsoft’owego. Zakładam, że czytelnik zna już algorytm Mark&Sweep. Pamięć alokowana w .NET jest przechowywana w tzw. generacjach. Istnieją 3 generacje:Generation 0 – zwolnienie obiektu z GEN0 jest szybkie i mało kosztowne. Przechowywane są w niej obiekty używane tylko przez krótki czas. Generation 1 – obiekty, które awansowały z GEN0. Zwolnienie zasobów w GE...
http://msdn.microsoft.com/pl-pl/library/prism–nawigacja-na-podstawie-zmiany-widokowExplore posts in the same categories:WPF
Artykuł ma na celu łagodne wprowadzenie czytelnika w świat PRISM. Dokumentacja, dostępna aktualnie na CodePlex lub MSDN, jest moim zdaniem zbyt skomplikowana dla osoby, która chce się w skrócie dowiedzieć, co oferuje programistom ten bardzo rozbudowany framework. http://msdn.microsoft.com/pl-pl/library/prism–modularne-aplikacje-wpf.aspxExplore posts in the same categories:Patterns & Practices, WPF
Aby pisać kod, który jest wydajny i optymalny należy dobrze zrozumieć jak działa Garbage Collector (GC). W dzisiejszym poście przedstawię ogólne zasady działania GC na przykładzie algorytmu mark and sweep. Zaznaczam, że implementacja w .NET różni się i jest dużo bardziej wyrafinowana – ale o tym w następnych postach. Chcę najpierw przedstawić algorytm mark and sweep ponieważ da to czytelnikowi ogólny obraz zagadnienia związanego ze zwalnianiem pamięci w językach zarządzanych. Garbage Collector oczywiści...
Co byście powiedzieli na taki kod?publicclass Person { publicstring FirstName; publicstring LastName; publicstring GetFullName() { returnstring.Format("{0} {1}", FirstName, LastName); } } Na pierwszy rzut oka może nic poważnego. Jednak jeśli chcemy pisać kod zgodny z praktykami C#, powinniśmy zwrócić uwagę na następujące kwestie:Enkapsulacja, FirstName,LastName powinni być ukryte i ewentualnie wyeksponowane za pomocą setterow\getterów.GetFullName jest dobrym sposobem dla Javy (a w...