Category Archives: Visual Studio

Fuslogvw a assembly binding

Czasami proste debugowanie za pomocą Visual Studio nie wystarcza. Sposób w jaki biblioteki są ładowane zależy od wielu czynników i plików konfiguracyjnych. Jeśli np. nasza aplikacja wyrzuca wyjątek “MissingMethodException”, a w czasie debugowania wszystko działa jak należy, wtedy możliwe, że mamy problemy związane z assembly binding.

Narzędzie Fuslogvw wchodzi w skład Visual Studio i pozwala prześledzić jakie kolejno biblioteki ładowane są. Dzięki temu poznamy ich lokalizacje oraz wersje.

W celu uruchomienia fuslogvw, odpalamy najpierw wiersz poleceń Developer Command Propmpt (koniecznie jako administrator):
1Następnie wpisujemy “Fuslogvw.exe”, co spowoduje uruchomienie narzędzia:
2

W “Settings” możemy ustawić czy chcemy wyłącznie logować błędy czy wszystkie wiązania:
3

Następnie stwórzmy jakaś aplikację (np. ConsoleApp) w celu zobaczenia co zaloguje Fuslogvw. Po odpaleniu przykładowej aplikacji naciskamy “Refresh” w Fuslogvw:
4

Na ekranie zobaczymy kilka nowych wpisów. Klikając na jedno z nich przejdziemy do szczegółów:
5

W szczegółach widzimy wyraźnie jaka biblioteka jest ładowana i skąd. Z kolei jeśli jakieś biblioteki nie można załadować, wtedy logi będą wyglądać następująco:
6

Na screenshocie można zauważyć, które  ścieżki są kolejno brane pod uwagę, gdy pliku dll nie ma w głównym katalogu aplikacji.

Visual Studio 15 Preview: Wykonywanie kodu w oknie Interactive.

O oknie “Interactive” pisałem już tutaj. Bardzo pożyteczna funkcja, w moim przypadku zastępująca LinqPad.

W wersji 15 Preview (którą można pobrać z stąd), dodano możliwość wykonywania zaznaczonego kodu. Załóżmy, że funkcja Main wygląda następująco:

1

Możliwe jest teraz zaznaczenie kodu i wykonanie go w oknie Interactive C#:

2

Warto zwrócić uwagę również na skrót – Ctrl+E. To bardzo pożyteczne, gdy chcemy szybo coś przetestować. Okno otworzy się automatycznie i zostanie wykonany zaznaczony kod:

3

Niby nic wielkiego, ale wiele razy musiałem otwierać LinqPad, albo w przypadku wersji 2015 ręcznie okno Interactive.

C# 7.0 – lokalne funkcje

Dzisiaj zaczynam pierwszy wpis o nowościach w C# 7.0. Przede wszystkim warto ściągnąć Visual Studio 15 Preview. Wersja 15, to przyszły następca Visual Studio 2015, który określany był wersją 14.

Jeśli chcemy sprawdzić nowości z C# 7.0 musimy najpierw ustawić  __DEMO__ oraz  __DEMO_EXPERIMENTAL__  we właściwościach projektu:

1

Pierwsza nowość to zagnieżdżone funkcję lokalne. Przykład:

    public class Test
    {
        public void DoSomething()
        {
            int GetValue(int a)
            {

                return a;
            }

            Console.WriteLine(GetValue(5));
        }
    }

Innymi słowy jest to funkcja w funkcji. Czasami deklarujemy prywatną metodę, która używana jest jedynie w jednej metodzie jako helper. Za pomocą lokalnej funkcji w łatwy sposób możemy ograniczyć jej zasięg.

Funkcja jest lokalna, zatem poniższy kod nie skompiluje się:

    public class Test
    {
        public void DoSomething()
        {
            int GetValue(int a)
            {

                return a;
            }

            Console.WriteLine(GetValue(5));
        }

        public void DoSomething1()
        {
            Console.WriteLine(GetValue(5));
        }
    }

Lokalną funkcję można tylko wywoływać w metodzie, w której ją zadeklarowano. Analogicznie poniższy kod wywoła błąd kompilacji:

    class Program
    {
        private static void Main(string[] args)
        {
            Test test = new Test();
            test.DoSomething();
            test.GetValue(5);
        }
    }

Co prawda można wywołać test.DoSomething, ale test.GetValue już nie.
Możliwe jest również deklarowanie funkcji zagnieżdżonych wielokrotnie, tzn.:

   public class Test
    {
        public void DoSomething()
        {
            int GetValue(int a)
            {
                string GetString(string b)
                {
                    return b;
                }

                Console.WriteLine(GetString(a.ToString()+" as text"));

                return a;
            }

            Console.WriteLine(GetValue(5));
        }
    }

Na ekranie najpierw wyświetli się “5 as text”, a potem 5. Z kolei następujący kod już nie skompiluje się:

    public class Test
    {
        public void DoSomething()
        {
            int GetValue(int a)
            {
                string GetString(string b)
                {
                    return b;
                }                

                return a;
            }

            Console.WriteLine(GetString(a.ToString() + " as text"));
        }
    }

Oznacza to, że z funkcji A można jedynie odnosić się do tej najbardziej zewnętrznej funkcji lokalnej. Nic z kolei nie stoi na przeszkodzie, aby zadeklarować kilka metod o tym samym stopniu zagnieżdżenia:

    public class Test
    {
        public void DoSomething()
        {
            int GetValue(int a)
            {              
                return a;
            }

            string GetString(string b)
            {
                return b;
            }


            Console.WriteLine(GetString("5 as text"));
            Console.WriteLine(GetValue(5));
        }
    }

Jakiekolwiek modyfikatory są zabronione, np. taki kod nie skompiluje się:


    public class Test
    {
        public void DoSomething()
        {
            static int GetValue(int a)
            {              
                return a;
            }
            Console.WriteLine(GetValue(5));
        }
    }

Analogicznie sprawa wygląda z public czy nawet private.
Możliwe jest z kolei z korzystanie z metod wyrażonych w formie lambda (nowość z c# 6.0):

    public class Test
    {
        public void DoSomething()
        {
            int GetValue(int a) => a;
      
            Console.WriteLine(GetValue(5));
        }
    }

Funkcja lokalna może mieć również dostęp do zmiennych zadeklarowanych w zewnętrznej funkcji, tzn.:

       public class Test
    {
        public void DoSomething()
        {
            int outerValue = 43;

            void Nested()
            {
                Console.WriteLine(outerValue);
                outerValue = 100;
            }

            Nested();
            Console.WriteLine(outerValue);
        }
    }

Na ekranie wyświetli się 43, a potem 100, ponieważ wartości kopiowane są w analogiczny sposób jak to ma miejsce w anonimowych funkcjach. Kolejne zagnieżdżenia mogą korzystać ze zmiennych zadeklarowanych w nadrzędnych funkcjach.

Na zakończenie warto spojrzeć co naprawdę jest wygenerowane w tle:

.class /*02000003*/ public auto ansi beforefieldinit 
  ConsoleApplication1.Test
    extends [mscorlib]System.Object
{

  .method /*06000003*/ public hidebysig instance void 
    DoSomething() cil managed 
  {
    .maxstack 8

    // [22 9 - 22 10]
    IL_0000: nop          
    IL_0001: nop          

    // [27 13 - 27 44]
    IL_0002: ldc.i4.5     
    IL_0003: call         int32 ConsoleApplication1.Test::'<DoSomething>g__GetValue0_0'(int32)
    IL_0008: call         void [mscorlib]System.Console::WriteLine(int32)
    IL_000d: nop          

    // [28 9 - 28 10]
    IL_000e: ret          

  } // end of method Test::DoSomething

  .method /*06000004*/ public hidebysig specialname rtspecialname instance void 
    .ctor() cil managed 
  {
    .maxstack 8

    IL_0000: ldarg.0      // this
    IL_0001: call         instance void [mscorlib]System.Object::.ctor()
    IL_0006: nop          
    IL_0007: ret          

  } // end of method Test::.ctor

  .method /*06000005*/ assembly hidebysig static int32 
    '<DoSomething>g__GetValue0_0'(
      /*08000002*/ int32 a
    ) cil managed 
  {
    .custom /*0C00000F*/ instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() /*06003F5F*/ 
      = (01 00 00 00 )
    .maxstack 1
    .locals init (
      [0] int32 V_0
    )

    // [24 13 - 24 14]
    IL_0000: nop          

    // [25 17 - 25 26]
    IL_0001: ldarg.0      // a
    IL_0002: stloc.0      // V_0
    IL_0003: br.s         IL_0005

    // [26 13 - 26 14]
    IL_0005: ldloc.0      // V_0
    IL_0006: ret          

  } // end of method Test::'<DoSomething>g__GetValue0_0'
} // end of class ConsoleApplication1.Tes

Warto zwrócić uwagę na dwie sygnatury:

 .method /*06000003*/ public hidebysig instance void 
    DoSomething() cil managed 
[/csharp

oraz


 .method /*06000005*/ assembly hidebysig static int32 
    '<DoSomething>g__GetValue0_0'(
      /*08000002*/ int32 a
    ) cil managed 

.

Innymi słowy, w praktyce dwie różne metody są generowane (lokalna funkcja to ta prywatna).

Visual Studio 2015 – okno C# interactive

W Visual Studio 2015 Update 1 można znaleźć nowe okno, a mianowicie C# interactive. Często chcemy przetestować kawałek kodu w izolacji od aplikacji nad którą aktualnie pracujemy. Zwykle korzystałem z LinqPad, ale posiadanie takiej funkcji od razu w Visual Studio jest wygodniejsze. Wystarczy z menu głównego wybrać View->Other Windows->C# Interactive:

1

Następnie możemy wykonać jakikolwiek kod, np.:

2

Jak widzimy, jeśli nie zakończymy linii kodu średnikiem, wtedy zawartość zostanie po prostu wyświetlona. Wpisując #help dostaniemy opis podstawowych instrukcji\operacji:

3

Ponadto, okno wspiera bardzo dobrze Intellisense:

4

Dobrze, że można również deklarować przestrzenie nazw, co nie jest może bardzo intuicyjne, ale za to przydaje się:

5

Nic nie stoi na przeszkodzie, aby zadeklarować własną klasę:

6

Możliwe jest również załadowanie zewnętrznych bibliotek. Jak widać, jest to bardzo przydatny notatnik C#, a do tego jak już piszemy kod w Visual Studuio, odpalenie okna jest dużo szybsze niż załadowanie LinqPad czy stworzenie aplikacji konsolowej w celu przetestowania czegoś.

Resharper: Postfix templates

Postfix templates to kolejne usprawnienie, dzięki któremu nie musimy korzystać co chwilę z myszki i skakać między liniami kodu. Postfix templates mają za zadanie uniknięcie cofania się kursorem do początku linii. Na przykład, jeśli definiujemy warunek, wtedy jeśli chcemy dodać IF, musimy cofnąć się. Podobnie z pętlami, using, lock i innymi konstrukcjami. Postfix oznacza, że szablon aplikujemy na końcu linii.

Postfix templates zostało zintegrowane z Resharper 10.0. Mój ulubiony szablon to “.var”. Bardzo często deklarujemy zmienne w następujący sposób:

var stringBuilder = new StringBuilder();

Za pomocą szablonów możemy napisać “StringBuilder.var” i zostanie wygenerowany powyższy kod. Ponadto, Intellitrace podpowie nam StringBuilder więc tak naprawdę będziemy musieli napisać coś w stylu “Str.var”. Screenshot:

1

Po naciśnięciu enter, zostanie wygenerowany kod:

2

Oczywiście trochę to zajmie czasu, aby zapamiętać wszystkie skróty szablonów oraz przyzwyczaić się do nich.  Na szczęście są one na tyle wygodne, że po pewnym czasie stają się tak naturalne, jak “alt+enter”.  Jeśli chcemy wyrzucić wyjątkiem wtedy wpisujemy:

3

Szablon wygeneruje oczywiście:

threw new NotImplementException();

Proszę zwrócić uwagę, że pierwsza cześć jest zawsze silnie typowana. Oznacza to, że w praktyce wystarczy, że naciśniemy kilka klawiszy i wyjątek zostanie wyrzucony (szczególnie, że nie ma spacji między nazwą wyjątku, a .throw). Wsparcie intellitrace jest jeszcze bardziej przydatne.

Kolejny przydatny szablon to .if. Najpierw piszemy warunek, np. a>5, a potem za pomocą .if wygenerujemy instrukcję warunkową:
4

Do dyspozycji mamy również różne typy pętli. Szczególnie interesującą jest .forr, czyli for iterujący od końca do początku tablicy:

5

Wygenerowany kod:

          for (var i = data.Length - 1; i >= 0; i--)
          {
              
          }

Z ciekawszych skrótów jest jeszcze: .null,.notnull czy .switch.

Pełna lista szablonów znajduje się tutaj. Nie chcę tutaj opisać każdej instrukcji osobno bo najlepiej po prostu popraktykować to samemu – na początku jest trudno przyzwyczaić się.

Resharper\Visual Studio: Kilka przydatnych skrótów, część II

Dzisiaj kolejna część o moich ulubionych skrótach.

1. Ctrl+[ – przejście do deklaracji metody. Szczególnie przydatne z pracą z legacy code, gdzie nie jest to zawsze takie oczywiste… Często korzystam  z tej komendy w połączeniu z Ctrl+R, czyli zmiany nazwy metody.  Inna kombinacja to Ctrl+Shift+[, która zaznacza całą deklarację metody (sygnatura + ciało).

2. Wszyscy chyba kojarzą skróty Ctrl+N\Ctrl+T, umożliwiające wyszukiwanie plików, klas oraz metod. Ciekawą rzeczą jest, że wspierana jest składnia Camsel Case. Jeśli mamy  klasę o nazwie SqlDataReader, wystarczy wpisać sdr i będziemy mieli dokładne dopasowanie. Chyba wszyscy programiści C# korzystają z CamelCase więc jest to bardzo ciekawe udogodnienie ze strony Resharper.

3. Shift+Alt+L – zaznacza plik danej klasy w solution explroer. Przydatne, gdy korzystamy najpierw z CTRL+T w celu znalezienia klasy, a potem chcemy zobaczyć gdzie ona znajduje się w solucji.

4. Ctrl+k+d – formatowanie kodu. Zamiast czekać aż zamkniemy klamrę, wystarczy skorzystać z tego skrótu w celu dodania uporządkowania kodu.

5. Ekstrakcja zmiennej – Crl+R, V. Często mamy metody, które jako parametry przyjmują serie innych wywołań np. Test(Test1(Test2())). Czasami jest to nieprzejrzyste i lepiej umieścić wywołania w osobnych liniach kodu np. int test2Value = Test2(); Zaznaczając dane wywołanie i naciskając wspomnianą kombinację, automatycznie zostanie wydobyta zmienna.

6. Ekstrakcja metod – Ctrl+R, M  – analogicznie, wystarczy zaznaczyć fragment kodu, a zostanie on przeniesiony do nowej metody.

7. Ekstrakcja pól – Ctrl+R, F

8. Jeśli tylko mogę to pracuję z nCrunch i wtedy po prostu nie muszę odpalać ręcznie testów. Jeśli nie mam tego luksusu, wtedy Resharper jest przydatny. Ctrl+U,L uruchomi wszystkie testy w danej solucji.

9. Ctrl+R,S – zmiana sygnatury. Jeśli tylko metoda jest zaznaczona (przydatny skrót Ctrl+[), wtedy pojawi się następujące okno:

1

 

Najczęściej korzystam ze zmiany kolejności parametrów. Resharper automatycznie zaktualizuje nie tylko sygnaturę, ale również wszelkie wywołania.

10. Nawigacja między metodami – Alt+Up albo Alt+Down – spowoduje przejście do kolejnej lub poprzedniej metody w danej klasie.

Resharper\Visual Studio: Kilka przydatnych skrótów, część I

Resharper’a nie trzeba nikomu przedstawiać. Co prawda, Visual Studio co każdą edycję dodaje trochę funkcjonalności wcześniej dostępnej tylko w Resharper, wciąż jednak jest to najpopularniejsze narzędzie w większości firmach.

Dzisiaj kilka moich ulubionych skrótów. Myślę, że ALT+ENTER oraz szukanie typów (ctrl+n,ctrl+t) nie trzeba przedstawiać więc pominę to 🙂

1. CTRL+E, U – wyświetla menu kontekstowego, w którym możemy wybrać szablon otaczający dany kod:

1

Szczególnie przydatne z try-catch. Zacznamy kod, potem CTRL+E, U,8 i mamy szybko obsługę wyjątków.

2. Wpisanie “ctor” oraz naciśnięcie enter, spowoduje wygenerowanie domyślnego konstruktora:

1

1

Co prawda jest to zwykły snippet, ale uważam, że zasługuje on na uwagę.

3. Alt+Ins. Gdy jesteśmy w Solution Explorer, naciśnięcie tej kombinacji, wyświetli menu kontekstowe umożliwiające dodanie np. nowej klasy:

1

Dużo wygodniejsze niż używanie myszki.

4. Ctrl+Shift+V – wyświetlenie schowka. Kopiowanie i wklejanie fragmentów kodu jest bardzo częstą czynnością programisty… Po naciśnięciu, dostaniemy okienko z ostatnimi zmianami w schowku:

1

5. Alt+Enter jest wszechobecne w Resharper. Jednym z ciekawych scenariuszy użycia jest string.Format. Jeśli napiszemy najpierw string.Format(“Hello world “) i naciśniemy Alt+Enter, zostanie wygenerowany automatycznie place holder “{0}” czyli  string.Format(“Hello {0}”, “ARG0”).

6. Ctrl + Shift + Alt + arrows. Załóżmy, że mamy następującą klasę:

    class SampleClass
    {
        private void Test() { }
        public void Method() { }
        public void Method2() { }
        public void Method3() { }
    }

Zawsze sortuję metody na podstawie modyfikatora – prywatne zwykle są na samym dole. Bez Resharper po prostu zaznaczyłbym metodę Test i przekopiował na sam dół (CTRL+X -> CTRL+V). Dużo wygodniejsze jest jednak CTRL+Shift+ALT+DOWN i naciśnięcie strzałki trzykrotnie. Komenda po prostu przeniesie daną część kodu (metodę) w dół. Nie trzeba nawet metody zaznaczać – wystarczy, że kursor znajduję się w podanej metodzie.

W następnym poście ciąg dalszy. Pomimo, że są to drobiazgi to bardzo usprawniają pracę – należy tylko o nich opamiętać…

Visual Studio 2013–konwersja JSON\XML do klas C#

W Visual Studio 2013 istnieje opcja “Paste  special”, gdzie możemy wkleić dowolny JSON lub XML jako klasy C#. Opcja jest mało znana, ale bardzo przydatna, gdy pracujemy z zewnętrznymi usługami. Często ręcznie tworzymy takie klasy w celu ich późniejszej deserializacji, np. za pomocą JSON.NET. Wystarczy, że przekopiujemy dokument JSON lub XML do schowka, a następnie z menu głównego wybierzemy:

image

Załóżmy, że w schowku mieliśmy:

{"employees":[ {"firstName":"John", "lastName":"Doe"}, {"firstName":"Anna", "lastName":"Smith"}, {"firstName":"Peter", "lastName":"Jones"} ]}

Wygenerowane klasy będą wyglądać następująco:

public class Rootobject { public Employee[] employees { get; set; } } public class Employee { public string firstName { get; set; } public string lastName { get; set; } }

Nie trzeba instalować żadnych zewnętrznych pluginów – jest to część VS.

Visual Studio 2015 RC– network

Niedawno pojawiła się wersja RC VS 2015. Wraz z nią, dodano nowe narzędzie diagnostyczne.  O  performance hub pisałem już wielokrotnie. Visual Studio coraz więcej narzędzi zewnętrznych wbudowuje w IDE. Mamy zatem już do dyspozycji profilery jak i o RC, diagnozowanie ruchu sieciowego.

Więcej szczegółów znajduje się tutaj:

http://blogs.msdn.com/b/visualstudio/archive/2015/05/04/introducing-visual-studio-s-network-tool.aspx

Załóżmy, że mamy prosty kod, który wykona połączenie HTTP:

HttpClient client = new HttpClient(); var response = client.GetAsync("http://www.pzielinski.com").Result; var content = response.Content.ReadAsStringAsync().Result; Console.WriteLine(content);

Dzięki nowemu narzędziu, będziemy wstanie prześledzić wszystkie połączenia tak jak to w przypadku zewnętrznych narzędzi typu Fiddler. Jest to bardzo przydatne w diagnozowaniu usług REST, które są dzisiaj wyjątkowo popularne.

Niestety nie udało mi się uruchomić Performance Hub Network na własnym komputerze ani nawet na Azure VM. Wszystkie próby kończyły się “diagnostics session failed to start “, co jest dosyć słabe jak na wersje RC… W poście posłużę się więc screenami z MSDN, które również znajdują na dodanym linku na początku postu.

Z menu głównego wybieramy zatem Debug –> Start Diagnostic Tools without debugging i zaznaczamy network:

image

Po naciśnięciu “Start”, zobaczymy najpierw okno Network Summary (źródło screenu MSDN Blogs):

Widzimy w oknie listę połączeń, zwróconych kodów, czasów wykonania itp. Jak to bywa w VS, okno jest interaktywne i możemy np. posortować wyniki oraz dostosować widok do naszych potrzeb. Aby nie przegapić najgroźniejszych kodów HTTP tzn. 4xx oraz 5xx, zostają one zaznaczone na czerwono (źródło screenu MSDN Blogs):

Możliwe jest również zapisanie danych do pliku i co najważniejsze wspierany jest format .har.  Dzięki temu możemy przeanalizować ruch w bardziej zaawansowanych narzędziach typu Fiddler. Przykładową zawartość pliku .har można znaleźć np. tutaj.

Klikając dwukrotnie na danej pozycji, dostaniemy dodatkowe informacje, takie jak pełna odpowiedź i zapytanie:

8321.BUILD2015_2D00_NetworkTool_2D00_Details-Panel.PNG (586×713)

Narzędzie nie dodaje nic nowego w porównaniu do tego, co było dostępne cały czas w Fiddler. Moim zdaniem jednak, dobrze, że takie narzędzia integrowane są z IDE. W erze usług RESTful, takie zadania jak podglądanie statusów HTTP są bardzo częste więc dobrze mieć je pod ręką.