La static
parola chiave 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 nessuna singola istanza della classe, ma invece alla classe stessa.
Senza entrare troppo nei dettagli, C # (e Java) impongono rigidamente l'ideale orientato agli oggetti che tutto il codice e i dati devono appartenere a un oggetto, e quindi sono limitati in ambito, visibilità e durata. Questa è generalmente la migliore pratica ovunque si applichi il principio fondamentale di un oggetto che rappresenta qualcosa del mondo reale. Tuttavia, non sempre; a volte ciò di cui hai bisogno è una funzione o una variabile a cui puoi accedere da qualsiasi parte del codice, senza la necessità di passare un riferimento a un oggetto che lo contiene e con la garanzia che i dati che stai osservando o modificando sono esattamente ciò che tutti else sta trattando, e non una sua copia appartenente a un'istanza diversa di un oggetto.
Tale comportamento era disponibile in C e C ++ nella forma della funzione o variabile "globale", che non era incapsulata in un oggetto. Quindi, come compromesso, C # e Java supportano "ambito statico", un punto a metà strada tra codice veramente globale senza oggetto padre e membri di istanza di ambito limitato.
Qualsiasi "membro del codice" (funzione, proprietà, campo) dichiarato static
rientrante nell'ambito della prima riga della main()
funzione del programma e non lo lascia fino al main()
termine della funzione. In parole povere, esiste un membro statico che può essere utilizzato finché il programma è in esecuzione. Inoltre, i membri statici vengono richiamati chiamandoli come membri del tipo stesso, non membri di una sola 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
Ciò rende i membri statici visibili a qualsiasi codice che abbia conoscenza del tipo, indipendentemente dal fatto che ne siano a conoscenza o meno.
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 utilizzatore abbia o possa ottenere un'istanza dell'oggetto contenente. C'è anche un leggero vantaggio in termini di prestazioni; poiché il metodo ha un ambito statico, può accedere solo ad altri membri statici (della stessa classe o di altri) e a qualunque cosa venga passata come parametro. Pertanto, il runtime non deve risolvere alcun riferimento all'istanza corrente dell'oggetto contenitore, come dovrebbe normalmente fare per un metodo di istanza al fine di fornire informazioni sullo stato specifiche del contesto.
Intere classi possono anche essere contrassegnate come statiche; in tal modo, si comunica 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, e una sola, copia di un oggetto in memoria; rendere la classe e tutto quanto in essa statica. Tuttavia, è molto raro che questa sia la migliore soluzione a tale esigenza. In una situazione in cui è richiesta esattamente una copia di una serie di dati, si consiglia invece il "singleton"; questa è una classe non statica, che utilizza un accessor statico e un costruttore non pubblico per fornire l'accesso a una singola istanza di se stessa. Teoricamente, un singleton offre più o meno gli stessi vantaggi di una classe completamente statica, ma con la possibilità aggiuntiva di usare la classe in un modo basato sull'istanza e orientato agli oggetti.