A Resharper piace sottolineare più funzioni per pagina asp.net che potrebbero essere rese statiche. Mi aiuta se li faccio statici? Devo renderli statici e spostarli in una classe di utilità?
A Resharper piace sottolineare più funzioni per pagina asp.net che potrebbero essere rese statiche. Mi aiuta se li faccio statici? Devo renderli statici e spostarli in una classe di utilità?
Risposte:
Metodi statici rispetto ai metodi di istanza
10.2.5 I membri statici e di istanza delle specifiche del linguaggio C # spiegano la differenza. In generale, i metodi statici possono fornire un miglioramento delle prestazioni molto ridotto rispetto ai metodi di istanza, ma solo in situazioni alquanto estreme (vedere questa risposta per ulteriori dettagli al riguardo).
La regola CA1822 in FxCop o Code Analysis afferma:
"Dopo [contrassegnare i membri come statici], il compilatore emetterà siti di chiamata non virtuali a questi membri che impediranno un controllo in fase di esecuzione per ogni chiamata che assicuri che il puntatore dell'oggetto corrente sia non nullo. Ciò può comportare un guadagno misurabile delle prestazioni per il codice sensibile alle prestazioni. In alcuni casi, il mancato accesso all'istanza dell'oggetto corrente rappresenta un problema di correttezza. "
Classe di utilità
Non spostarli in una classe di utilità a meno che non abbia senso nella progettazione. Se il metodo statico si riferisce a un tipo particolare, come un ToRadians(double degrees)
metodo si riferisce a una classe che rappresenta gli angoli, ha senso che quel metodo esista come un membro statico di quel tipo (nota, questo è un esempio contorto ai fini della dimostrazione).
Le prestazioni, l'inquinamento dello spazio dei nomi, ecc. Sono tutti secondari secondo me. Chiediti cosa è logico. Il metodo funziona logicamente su un'istanza del tipo o è correlato al tipo stesso? Se è quest'ultimo, rendilo un metodo statico. Spostalo in una classe di utilità solo se è correlato a un tipo che non è sotto il tuo controllo.
A volte ci sono metodi che logicamente agiscono su un'istanza, ma non capita di utilizzare una qualsiasi delle Stato dell'istanza ancora . Ad esempio, se stavi costruendo un file system e avessi ottenuto il concetto di directory, ma non lo avessi ancora implementato, potresti scrivere una proprietà che restituisca il tipo di oggetto del file system e sarebbe sempre "file" - ma è logicamente correlato all'istanza e quindi dovrebbe essere un metodo di istanza. Ciò è importante anche se si desidera rendere virtuale il metodo: l'implementazione particolare potrebbe non richiedere stato, ma le classi derivate potrebbero. (Ad esempio, chiedendo a una raccolta se è di sola lettura - potresti non aver ancora implementato un modulo di sola lettura di quella raccolta, ma è chiaramente una proprietà della raccolta stessa, non del tipo.)
Contrassegnare un metodo come static
all'interno di una classe rende ovvio che non utilizza alcun membro di istanza, il che può essere utile sapere quando si scorre il codice.
Non devi necessariamente spostarlo in un'altra classe a meno che non sia pensato per essere condiviso da un'altra classe che è strettamente associata, dal punto di vista concettuale.
Sono sicuro che questo non sta accadendo nel tuo caso, ma un "cattivo odore" che ho visto in alcuni codici che ho dovuto soffrire per aver usato un sacco di metodi statici.
Sfortunatamente, si trattava di metodi statici che presupponevano un particolare stato dell'applicazione. (perché certo, avremo un solo utente per applicazione! Perché non fare in modo che la classe User tenga traccia di ciò nelle variabili statiche?) Erano modi glorificati per accedere alle variabili globali. Avevano anche costruttori statici (!), Che sono quasi sempre una cattiva idea. (So che ci sono un paio di eccezioni ragionevoli).
Tuttavia, i metodi statici sono piuttosto utili quando escludono la logica di dominio che in realtà non dipende dallo stato di un'istanza dell'oggetto. Possono rendere il tuo codice molto più leggibile.
Assicurati solo di metterli nel posto giusto. I metodi statici stanno manipolando in modo intrusivo lo stato interno di altri oggetti? Si può sostenere che il loro comportamento appartiene invece a una di quelle classi? Se non stai separando correttamente le preoccupazioni, potresti avere mal di testa in seguito.
Questo è interessante leggi:
http://thecuttingledge.com/?p=57
ReSharper non sta effettivamente suggerendo di rendere statico il metodo. Dovresti chiederti perché quel metodo è in quella classe invece di, diciamo, una delle classi che appare nella sua firma ...
ma ecco cosa dice documentaion resharper: http://confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static
Giusto per aggiungere al di @ Jason Vero risposta , è importante rendersi conto che solo mettendo 'statica' su un metodo non garantisce che il metodo sarà 'pura'. Sarà apolide rispetto alla classe in cui viene dichiarato, ma potrebbe anche accedere ad altri oggetti "statici" con stato (configurazione dell'applicazione ecc.), Questo potrebbe non essere sempre una cosa negativa, ma uno dei motivi per cui Personalmente tendo a preferire metodi statici quando posso che se sono puri, puoi testarli e ragionarli in modo isolato, senza doversi preoccupare dello stato circostante.
Dovresti fare ciò che è più leggibile e intuitivo in un determinato scenario.
L'argomento delle prestazioni non è valido tranne nelle situazioni più estreme poiché l'unica cosa che sta effettivamente accadendo è che un parametro aggiuntivo ( this
) viene inserito nello stack per i metodi di istanza.
Per la logica complessa all'interno di una classe, ho trovato utili metodi statici privati nella creazione di una logica isolata, in cui gli input dell'istanza sono chiaramente definiti nella firma del metodo e non possono verificarsi effetti collaterali dell'istanza. Tutte le uscite devono essere tramite valore di ritorno o parametri out / ref. Abbattere la logica complessa in blocchi di codice privi di effetti collaterali può migliorare la leggibilità del codice e la fiducia del team di sviluppo in esso.
D'altra parte può portare a una classe inquinata da una proliferazione di metodi di utilità. Come al solito, la denominazione logica, la documentazione e l'applicazione coerente delle convenzioni di codifica del team possono alleviarlo.
Rendere statico un metodo significa che puoi chiamare il metodo dall'esterno della classe senza prima creare un'istanza di quella classe. Ciò è utile quando si lavora con oggetti o componenti aggiuntivi di fornitori di terze parti. Immagina di dover prima creare un oggetto console "con" prima di chiamare con.Writeline ();
Aiuta a controllare l'inquinamento dello spazio dei nomi.
Class.a_core_function( .. )
vsa_core_function( .. )
Solo la mia tuppenza: l'aggiunta di tutti i metodi statici condivisi a una classe di utilità consente di aggiungere
using static className;
alle tue istruzioni using, che rendono il codice più veloce da digitare e più facile da leggere. Ad esempio, ho un gran numero di quelle che verrebbero chiamate "variabili globali" in un codice che ho ereditato. Invece di creare variabili globali in una classe che era una classe di istanza, le ho impostate tutte come proprietà statiche di una classe globale. Fa il lavoro, anche se in modo disordinato, e posso solo fare riferimento alle proprietà per nome perché ho già lo spazio dei nomi statico a cui si fa riferimento.
Non ho idea se questa è una buona pratica o no. Ho così tanto da imparare su C # 4/5 e così tanto codice legacy da refactoring che sto solo cercando di lasciarmi guidare dai suggerimenti di Roselyn.
Joey
Spero che tu abbia già capito la differenza tra i metodi statici e quelli di istanza. Inoltre, può esserci una risposta lunga e una risposta breve. Le risposte lunghe sono già fornite da altri.
La mia breve risposta: Sì, puoi convertirli in metodi statici se Resharper suggerisce. Non c'è nulla di male nel farlo. Piuttosto, rendendo statico il metodo, stai effettivamente proteggendo il metodo in modo che, inutilmente, non scivoli alcun membro dell'istanza su quel metodo. In questo modo, è possibile ottenere un principio OOP " Ridurre al minimo l'accessibilità di classi e membri ".
Quando ReSharper suggerisce che un metodo di istanza può essere convertito in un metodo statico, in realtà ti dice: "Perché il .. questo metodo si trova in questa classe in quanto non sta effettivamente utilizzando nessuno dei suoi stati?" Quindi, ti dà spunti di riflessione. Quindi, sei tu che puoi capire la necessità di spostare quel metodo in una classe di utilità statica o meno. Secondo i principi SOLID, una classe dovrebbe avere una sola responsabilità fondamentale. Quindi, puoi fare una migliore pulizia delle tue lezioni in quel modo. A volte, hai bisogno di alcuni metodi di supporto anche nella tua classe di istanza. In tal caso, puoi tenerli all'interno di un helper #region.