Niedawno spotkałem się z zabawnym bugiem w Visual Studio. Zauważyłem go w VS 2005, ale udało mi się go odtworzyć w VS 2010, zresztą nie jest to trudne. Poniżej bardzo prosty kawałek kodu, który pozwoli wyjaśnić o co chodzi:
Powtarzając tą samą operację po zatrzymaniu programu na drugiej pułapce otrzyma natomiast taki wynik:
W "magiczny" sposób składowa prywatna, która powinna mieć wartość null przyjęła nagle wartość "Ala ma kota". Analogicznie parametr s przyjął wartość null zamiast "Ala ma kota". Na tym nie koniec. Poniższy obrazek pokazuje jak środowisko VS raportuje NullReferenceException i równocześnie pokazuje, że podejrzana referencja nie jest pusta.
Oczywiście nie ma w tym żadnej magii. Moim zdaniem to ewidentny bug w Visual Studio, spowodowany tym, że środowisko nie uwzględnia zasięgu obowiązywania składowych klas czy też parametrów metod. Z drugiej strony nazywanie w taki sam sposób zmiennych lokalnych, parametrów czy składowych klas, których zasięgi leksykalne pokrywają się, nie jest dobrym pomysłem bo prowadzi do bałaganu i pomyłek. W każdym razie wbrew pozorom w szale debugowania łatwo się na to złapać.
public class Fun { private string s = null; public void Test(string s) { Test2(); } public void Test2() { Console.WriteLine(s); } } ... new Fun().Test("Ala ma kota");Stawiamy pułapkę na początku metody Test oraz Test2 i uruchamiamy program. Po zatrzymaniu programu na pierwszej pułapce sprawdzamy wartość parametru s oraz prywatnej składowej klasy o tej samej nazwie. Otrzymamy taki wynik:
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWHncaGvnEHhyphenhyphen93qmVY5FHFcGQ7rLkfvPG_N2PZlYzoaLBc_YnsySBTIrw9w0PWKiCezYPABwRpCXEqQt1T1TxDd_MBZQzcZeeUVa-BZSn4JEUFxw2miDTvBmBcVjfNv7mEoMCGEULe2nz/s400/bug_w_VS_1.jpg)
Powtarzając tą samą operację po zatrzymaniu programu na drugiej pułapce otrzyma natomiast taki wynik:
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5U50pJVUg6Bt50MP5qvcbkCrbaJnWeL2OpAWyf8cK9l558U1D-i9ZlviHYEFRPNxympk9cBysIhpp3LRaRPyb63NW8lJAJSobms-NxEVAWMmwB7327eZsOeUge-psBg-9z5V2tDZWjMbo/s400/bug_w_VS_2.jpg)
W "magiczny" sposób składowa prywatna, która powinna mieć wartość null przyjęła nagle wartość "Ala ma kota". Analogicznie parametr s przyjął wartość null zamiast "Ala ma kota". Na tym nie koniec. Poniższy obrazek pokazuje jak środowisko VS raportuje NullReferenceException i równocześnie pokazuje, że podejrzana referencja nie jest pusta.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3p_PIZCX9ztUmw2IjMalzTwe97bM3Cw3p7bsvnvynBkLVxz3-SjhnFvwps0Q9kjB0Pcps0hdoU95BCOUdDOkRaZ-oHQGooHV72RFP1PvmlljOuLPeLSOJ7Pify_uah0Q8DI99tVPMSOB2/s400/bug_w_VS_3.jpg)
Oczywiście nie ma w tym żadnej magii. Moim zdaniem to ewidentny bug w Visual Studio, spowodowany tym, że środowisko nie uwzględnia zasięgu obowiązywania składowych klas czy też parametrów metod. Z drugiej strony nazywanie w taki sam sposób zmiennych lokalnych, parametrów czy składowych klas, których zasięgi leksykalne pokrywają się, nie jest dobrym pomysłem bo prowadzi do bałaganu i pomyłek. W każdym razie wbrew pozorom w szale debugowania łatwo się na to złapać.
8 comments:
Dodaj obie zmienne do watcha, będziesz miał kontekst. Moim zdaniem VS zachowuje się poprawnie.
Moim zdaniem też jest poprawnie. Skoro w metodzie Test utworzyłeś nową zmienną o nazwie "s", którą nadpisałeś pole z klasy, to będąc w kontekście tej metody oznacza ona coś innego.
Watch zadziała jeśli zmienna "s" oraz składowa "this.s" zostaną do niego dodane z palca. Jeśli użyjemy polecenie "Add Watch" z menu kontekstowego to otrzymamy efekt opisany przeze mnie. Podobnie w przypadku "Quick Watch".
Dla mnie jest to bug ponieważ pracując z VS chciałbym korzystać z wszystkich jego funkcji nie zastanawiając się czy w danym scenariuszu będą działać tak jak tego oczekuję.
"Skoro w metodzie Test utworzyłeś nową zmienną o nazwie "s", którą nadpisałeś pole z klasy, to będąc w kontekście tej metody oznacza ona coś innego."
Zgadza się. Zmienna lokalna przysłania w obrębie metody składową klasy (aby odwołać się do składowej musimy użyć słowa kluczowego "this"). Ja czepiam się tego, że VS pokazuje dla składowej klasy (zmiennej lokalnej) inną wartość niż ma ona w rzeczywistości. Widać to na obrazkach w dymkach "Pin To Source" wyświetlonych dla: parametru metody, definicji składowej oraz użycia tejże składowej.
Ok. Jasne. Przeoczyłem chyba istotę buga :) Faktycznie jest niepoprawnie.
Tez nie rozumiem, w czym blad? Wszystko sie zgadza.
"...Wszystko sie zgadza."
Jeśli dana zmienna ma wartość "null", a VS pokazuje, że ma inną wartość (w tym przypadku "Ala ma kota") to uważam, że nic się nie zgadza.
a mi się wydaje (nie jest to wrażenie na podstawie tylko i wyłącznie tego posta), że ewidentnie nudzisz się w pracy. większość twoich wpisów nie nadaje się na dotnetomaniaka.
Post a Comment