Słowo static
kluczowe może być trochę trudne do zrozumienia dla początkujących. Jego podstawowym celem jest identyfikacja członka klasy, który nie należy do żadnej pojedynczej instancji klasy, ale zamiast do samej klasy.
Bez wchodzenia w zbyt wiele szczegółów, C # (i Java) sztywno egzekwują zorientowany obiektowo ideał, że cały kod i dane muszą należeć do obiektu, a zatem mają ograniczony zakres, widoczność i żywotność. Jest to ogólnie najlepsza praktyka wszędzie tam, gdzie ma zastosowanie podstawowa zasada obiektu reprezentującego jakąś rzeczywistość. Jednak nie zawsze; czasami potrzebna jest funkcja lub zmienna, do której można uzyskać dostęp z dowolnego miejsca w kodzie, bez konieczności przekazywania odniesienia do obiektu zawierającego ją, a także z gwarancją, że dane, które oglądasz lub zmieniasz, są dokładnie tym , co wszyscy else ma do czynienia, a nie jego kopię należącą do innej instancji obiektu.
Takie zachowanie było dostępne w C i C ++ w postaci funkcji lub zmiennej „globalnej”, która nie została zamknięta w obiekcie. Tak więc, jako kompromis, C # i Java obsługują „zakres statyczny”, półmetka między prawdziwie globalnym kodem bez obiektu nadrzędnego i elementami instancji o ograniczonym zakresie.
Każdy „element kodu” (funkcja, właściwość, pole) zadeklarowany jako static
wchodzi w zakres od pierwszego wiersza funkcji programu main()
i nie opuszcza go, dopóki main()
funkcja się nie zakończy. W zwykłym języku angielskim istnieje element statyczny i można go używać, dopóki program jest uruchomiony. Ponadto elementy statyczne są wywoływane przez wywoływanie ich jako członków samego typu, a nie członków jednej instancji tego typu:
public class Foo
{
public int MyInt {get;set;} //this is an "instance member"
public static int MyStaticInt {get;set;} //this is a "static member"
}
...
var myFoo = new Foo();
myFoo.MyInt = 5; //valid
myFoo.MyStaticInt = 5; //invalid; MyStaticInt doesn't belong to any one Foo
Foo.MyInt = 5; //invalid; MyInt only has meaning in the context of an instance
Foo.MyStaticInt = 2; //valid
Dzięki temu elementy statyczne są widoczne dla każdego kodu, który ma wiedzę o typie, niezależnie od tego, czy wiedzą o jakimkolwiek pojedynczym wystąpieniu tego kodu.
Aby odpowiedzieć na twoje pytanie, podstawową zaletą oznaczenia czegoś jako statycznego jest to, że staje się on widoczny wszędzie tam, gdzie znany jest sam typ, niezależnie od tego, czy konsumujący kod ma lub może uzyskać instancję zawierającego obiekt. Istnieje również niewielka poprawa wydajności; ponieważ metoda ma zakres statyczny, może uzyskiwać dostęp tylko do innych elementów statycznych (tej samej klasy lub innych) i do wszystkiego, co jest przekazywane jako parametr. Dlatego środowisko wykonawcze nie musi rozpoznawać żadnego odwołania do bieżącej instancji obiektu zawierającego, tak jak zwykle w przypadku metody instancji w celu zapewnienia informacji o stanie specyficznych dla kontekstu.
Całe klasy można również oznaczyć statycznie; robiąc to, informujesz kompilator, że deklaracja klasy będzie składać się wyłącznie z elementów statycznych, a zatem nie może być utworzona. Jest to łatwy sposób na upewnienie się, że w pamięci jest jedna i tylko jedna kopia obiektu; uczyń klasę i wszystko w niej statycznym. Jednak bardzo rzadko jest to najlepsze rozwiązanie takiej potrzeby. W sytuacji, gdy wymagana jest dokładnie jedna kopia zestawu danych, zwykle zaleca się stosowanie „singletonu”; jest to klasa niestatyczna, która używa statycznego akcesora i niepublicznego konstruktora, aby zapewnić dostęp do pojedynczej instancji samego siebie. Teoretycznie singleton zapewnia te same korzyści, co klasa w pełni statyczna, ale z dodatkową możliwością korzystania z klasy w sposób obiektowy i obiektowy.