Słowo kluczowe static używane jest do tworzenia elementów statycznych takich jak zmienna, metoda, klasa, operator, itd. Bez niego nie można byłoby zrobić wielu rzeczy. Wydaje mi się, że jest ono czasami nadużywane. Co więcej, często osoby, które je wykorzystują nie zdają sobie sprawy z niebezpieczeństw z nim związanymi.
Znajomy programista, z którym miałem przyjemność pracować mawiał, że każde użycie słowa static powoduje śmierć jednego programisty. I w sumie miał rację. Niejednokrotnie zdarzało nam się w trakcie refaktoryzacji zmieniać byty statyczne, na zwykłe.
Wydaje mi się, że najlepszym sposobem przedstawienia problemu będzie posłużenie się następującym przykładem:
public static class A { public static int a = B.b + 1; } public static class B { public static int b = A.a + 1; } public class Program { static void Main(string[] args) { Console.WriteLine("a: " + A.a); Console.WriteLine("b: " + B.b); } }
I na koniec pytanie. Co się stanie, kiedy będę chciał skompilować ten fragment kodu i go uruchomić?
„każde użycie słowa static powoduje śmierć jednego programisty” -- piękne słowa, nic dodać nic ująć.
Dokładnie. W sumie nic nie muszę dodawać.
A na koniec jeszcze jedna uwaga. Efekt może być jeszcze ciekawszy, gdybyśmy każde Console.WriteLine uruchomili w osobnym wątku. Wtedy nie mielibyśmy pewności jaki otrzymamy wynik. Wszystko zależy od tego, która linijka wykona się szybciej.
Gdybyś zamienił kolejność definicji klas to zagadka byłaby ciekawsza, bo wynik się nie zmieni i wygląda na to, że pola statyczne są inicjalizowane w kolejności alfabetycznej, a nie w kolejności wystąpienia w programie, co jest niezłą niespodzianką.
A tak wszystko jest logiczne, pierw zmienne „a” i „b” są ustawiane na 0 jako że lądują na stercie, pierw jest inicjalizowane „a” które odwołuje się do „b”, czym uruchamia inicjalizacje b. A jest już oznaczone jako zainicjalizowane (pomimo tego że defacto proces ten się nie skończył), więc „b” pobiera wartość „a”, która wynosi 0, dodaje 1, wiec „b” =1 co jest zwracane do „a” które wynosi 2. Proste :D.
Program się kompiluje, a =2 b =1. Chętnie się dowiem czemu tak się dzieje…