La parola chiave static
può essere un po 'difficile da comprendere per i neofiti. Il suo scopo principale è quello di identificare un membro della classe come non appartenente a una singola istanza della classe, ma piuttosto alla classe stessa.
Senza entrare troppo nel dettaglio, C # (e Java) impongono rigidamente l'ideale orientato agli oggetti che tutto il codice e i dati devono appartenere a un oggetto, e quindi è limitato in ambito, visibilità e durata. Questa è generalmente la migliore pratica ovunque si applichi il principio fondamentale di un oggetto che rappresenta una cosa del mondo reale. Tuttavia, non sempre; a volte ciò di cui hai bisogno è una funzione o una variabile che puoi ottenere da ovunque nel codice, senza che tu debba passare un riferimento a un oggetto che lo contiene e con la garanzia che i dati che stai cercando ao cambiare è esattamente ciò che tutti gli altri hanno a che fare, e non una copia di esso appartenente a una diversa istanza di un oggetto.
Tale comportamento era disponibile in C e C ++ sotto forma di funzione o variabile "globale", che non era incapsulato in un oggetto. Quindi, come compromesso, C # e Java supportano "scope statico", un punto a metà tra il codice veramente globale con nessun oggetto principale e membri di istanze con ambito limitato.
Qualsiasi "membro di codice" (funzione, proprietà, campo) dichiarato come static
rientra nell'ambito della prima riga della funzione main()
del programma e non lo lascia finché la funzione main()
non termina. In inglese semplice, esiste un membro statico che può essere utilizzato fino a quando il programma è in esecuzione. Inoltre, i membri statici vengono richiamati chiamandoli come membri del tipo stesso, non membri di una qualsiasi istanza di quel tipo:
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
Questo rende i membri statici visibili a qualsiasi codice che abbia conoscenza del tipo, indipendentemente dal fatto che siano a conoscenza di una singola istanza.
Per rispondere alla tua domanda, il vantaggio principale di contrassegnare qualcosa come statico è che diventa visibile ovunque sia noto il tipo stesso, indipendentemente dal fatto che il codice di consumo abbia o possa ottenere un'istanza dell'oggetto contenente. C'è anche un lieve vantaggio in termini di prestazioni; poiché il metodo è in ambito statico, può solo accedere ad altri membri statici (della stessa classe o di altri) e qualsiasi cosa venga passata come parametro. Pertanto, il runtime non deve risolvere alcun riferimento all'istanza corrente dell'oggetto contenitore, come normalmente dovrebbe fare per un metodo di istanza al fine di fornire informazioni sullo stato specifiche del contesto.
Anche intere classi possono essere contrassegnate come statiche; così facendo, dici al compilatore che la dichiarazione di classe sarà composta esclusivamente da membri statici e quindi non può essere istanziata. Questo è un modo semplice per assicurarsi che ci sia una sola copia di un oggetto in memoria; rendere la classe e tutto ciò che è statico. Tuttavia, è molto raro che questa sia la soluzione migliore a tale necessità. In una situazione in cui è richiesta esattamente una sola copia di un insieme di dati, il "singleton" viene in genere consigliato; questa è una classe non statica, che utilizza un accessorio statico e un costruttore non pubblico per fornire l'accesso a una singola istanza di se stesso. In teoria, un singleton offre gli stessi vantaggi di una classe completamente statica, ma con la capacità aggiuntiva di utilizzare la classe in un modo basato sull'istanza e orientato agli oggetti.