2015-12-08 17 views
13

Tutta la mia squadra di sviluppo pensa che i metodi statici siano una cosa terribile da usare.I metodi statici sono sempre tenuti in memoria?

In realtà non vedo alcun svantaggio in alcuni casi. Quando avevo bisogno di un metodo stateless prima, ho sempre usato metodi statici per questo scopo.

Sono d'accordo su alcuni dei loro punti, ad es. So che sono abbastanza difficili da testare (anche se non è impossibile).

Quello che non ottengo è che, sostengono, i metodi statici sono sempre in memoria e riempiranno l'utilizzo di memoria di base. Quindi, se stai usando 100 metodi statici nel tuo programma, quando il programma inizia tutti i metodi sono caricati in memoria e riempiranno la memoria inutilmente. Ulteriori metodi più statici aumentano il rischio di mancanze di memoria.

È vero?

È piuttosto scomodo dover creare una nuova istanza di una classe solo per chiamare il metodo. Ma questo è come lo fanno adesso, creare un'istanza nel mezzo di un metodo e chiamare quel metodo, che potrebbe essere solo statico.

+0

http://programmers.stackexchange.com/questions/161222/dont-use-static-in-c – Irshad

+0

E questo; http://stackoverflow.com/questions/12279438/performance-of-static-methods-vs-instance-methods – Irshad

+2

_ "La mia intera squadra di sviluppo pensa che i metodi statici siano una cosa terribile da usare" _ - Immagino che vadano bene di cose utili come 'String.Compare()' troppo? – MickyD

risposta

4

Non esiste alcuna distinzione tra i metodi statico e di istanza per quanto riguarda la memoria. I metodi di istanza hanno solo un argomento aggiuntivo, this. Tutto il resto è esattamente lo lo stesso. Anche il modo basilare in cui i metodi di estensione sono stati facili da aggiungere a C#, tutto ciò che era necessario era la sintassi per esporre quell'argomento nascosto.

I metodi occupano spazio per il loro codice macchina, il codice effettivo eseguito dal processore. E una tabella che descrive come il metodo memorizza gli oggetti, che aiuta il garbage collector a scoprire le radici degli oggetti contenute nelle variabili locali e nei registri della CPU. Questo spazio è preso dal "caricatore di heap", una struttura di dati interna creata dal CLR associato all'appDomain. Succede solo una volta, quando il metodo viene eseguito per primo, just-in-time. Il rilascio di tale spazio richiede lo scaricamento di tale appdomain. Le variabili statiche sono anche allocate nell'heap del caricatore.

Non buttare via il grande vantaggio dei metodi statici. Possono migliorare notevolmente la leggibilità e la manutenibilità del codice. Grazie al loro contratto, non possono alterare lo stato dell'oggetto. Possono quindi avere pochissimi effetti collaterali, è davvero facile ragionare su quello che fanno. Tuttavia, se ti fanno aggiungere variabili statiche, fanno esattamente l'opposto, le variabili globali sono malvagie.

8

È piuttosto scomodo dover creare una nuova istanza di una classe solo per chiamare il metodo. Ma ecco come lo fanno adesso

Sono ridicoli, per essere schietti.

Come indicato da commenter Groo, al livello di compilazione nativo, un metodo di istanza non è nemmeno molto diverso da un metodo statico. È solo che è stato passato un parametro implicito al metodo di istanza, mentre con il metodo statico "ciò che vedi è ciò che ottieni".

Il runtime può ottimizzare l'accesso a un metodo. Potrebbe non compilare JIT il metodo fino alla prima esecuzione. Potrebbe anche non caricare l'IL dall'assembly in memoria fino a quando l'IL non è effettivamente necessario. Ma può eseguire queste ottimizzazioni con metodi statici e di istanza ugualmente bene.

In effetti, forzare tutti i metodi a essere metodi di istanza è peggiore di rispetto all'utilizzo del metodo statico, perché significa che per alcuni metodi, uno sta creando arbitrariamente un oggetto altrimenti inutile. Mentre il runtime può essere in grado di rilevare il riferimento all'oggetto non utilizzato e quindi farlo avere una durata minima, non può evitare di allocare del tutto l'oggetto, anche un oggetto degenerato occuperà parte della memoria mentre è vivo, e aggiungerà al costo della raccolta dei rifiuti.


E oltre a tutto ciò, supponiamo per un momento che i vostri colleghi abbiano ragione. Cosa avresti guadagnato? Qualche differenza di prestazioni misurabile? Dubbioso. Ammettiamolo: il codice gestito, e in particolare C#, ha il potenziale per nascondere qualsiasi numero di dettagli di implementazione privi di prestazioni da noi. Il motivo principale per cui utilizziamo un linguaggio di codice gestito come C# è che otteniamo così tanto in termini di produttività e correttezza del codice, che queste possibili inefficienze valgono la pena. Il più delle volte, e in particolare sui computer moderni, sono praticamente invisibili.

Come spesso accade, i vostri colleghi sono non corretta, e non è in alcun modo utile per fare in metodi di istanza, i metodi che altrimenti potrebbero essere metodi statici. Ma anche se così non fosse, dedicare del tempo a scrivere codice offuscato e inespresso per evitare un costo di prestazione non misurato e non dimostrato è uno spreco.(E so che nessuno si è preoccupato di confrontare le reali differenze di rendimento, perché se lo avessero fatto, non avrebbero trovato alcun miglioramento nelle prestazioni eliminando tutti i metodi statici).