2009-07-26 26 views
29

Supponiamo di disporre di un metodo che potrebbe essere reso statico, all'interno di una classe non statica.
Per esempio:Metodo statico e metodo non statico

private double power(double a, double b) 
    { 
     return (Math.Pow(a, b)); 
    } 

Non si vede alcun beneficio dalla modifica della firma del metodo in statica? Nell'esempio di cui sopra:

private static double power(double a, double b) 
    { 
     return (Math.Pow(a, b)); 
    } 

Anche se c'è qualche guadagno di prestazioni o la memoria, non sarebbe il compilatore lo fa come un semplice ottimizzazione in fase di compilazione?


Modifica: Quello che sto cercando sono i vantaggi dichiarando il metodo come statico. I so che questa è la pratica comune. Mi piacerebbe capire la logica dietro.
E, naturalmente, questo metodo è solo un esempio per chiarire la mia intenzione.

+0

@Everyone, so che questa è una domanda "antica" negli anni di sviluppo, ma è ancora attuale oggi. Molte ** risposte ** eccellenti di seguito. Hai bisogno di numeri di prestazioni reali per il tuo scenario specifico? Scrivi un programma rapido che chiama il metodo abbastanza volte (tra un 'var start = DateTime.Now()' e 'var end = DateTime.Now()') per poter avere un periodo di tempo abbastanza grande da confrontare. Eseguilo alcune volte con 'static' e alcune volte senza' static' e confronta la differenza. Magari apri TaskManager e osserva anche l'utilizzo della memoria per ogni scenario. –

+0

Solo per completezza, invece di confrontare la differenza tra i due 'DateTime.Now()', utilizzare la classe ['StopWatch'] (https://msdn.microsoft.com/en-us/library/system.diagnostics. cronometro (v = vs.110) .aspx). MODIFICA - Perché? È più preciso e più facile da usare rispetto al modo 'DateTime.Now()'. –

risposta

7

Si noti che è altamente improbabile che il compilatore possa persino apportare tale modifica a suo nome poiché modifica la firma del metodo. Di conseguenza, alcuni riflessi elaborati con cura (se ne stai usando uno qualsiasi) potrebbero smettere di funzionare, e il compilatore non può davvero sapere se questo è il caso.

+0

Buon punto. Non ci ho pensato, grazie. – Elad

1

questo metodo deve essere statico perché non è correlato alla classe o al membro delle classi. funziona solo con gli input per questa funzione.

forse potrebbe essere necessario chiamarlo senza creare quella classe. quindi se è statico va bene, ma se non lo è, non puoi chiamarlo senza alcuna istanza di quella classe.


I vantaggi di un metodo statico:

non c'è bisogno di creare un oggetto prima. Il metodo è disponibile immediatamente.

È utile quando si dispone di funzionalità generiche che non dipendono dallo stato di un particolare oggetto. Ad esempio, guarda la classe Array o la classe Collections da java.util.

I metodi statici possono essere utili per le fabbriche. Passa le tue esigenze come parametri, riavere un oggetto nuovo di zecca. Non è un costruttore in vista.

svantaggi di un metodo statico:

non devi un'istanza di un oggetto, in modo da avere accesso solo ai membri statici e le proprie variabili locali. Se vuoi un'istanza, probabilmente devi crearla da solo.

È possibile creare sottoclassi, ma un metodo statico non può essere astratto, quindi è più difficile disaccoppiare l'implementazione da un chiamante.


(ps: non penso compilatore di ottimizzare se sta per essere statici o no .. ma non sono sicuro)

33

Come definito, power è senza stato e non ha effetti collaterali su qualsiasi classe di inclusione quindi dovrebbe essere dichiarato static.

Questo article da MSDN va ad alcune delle differenze di prestazioni tra non statico e statico. La chiamata è circa quattro volte più veloce dell'istanziazione e della chiamata, ma in realtà è importante solo in un ciclo stretto che è un collo di bottiglia delle prestazioni.

+0

Dov'è il link? –

+0

@niko: modificato. Scusa e grazie. – jason

+0

+1 per il collegamento msdn. –

2

Per me una domanda facile da decidere è "Devo istanziare questo oggetto solo per chiamare questa funzione". Nel caso della tua funzione, direi che la risposta è no, quindi dovrebbe essere statico. Questo metodo non sembra essere correlato al tuo oggetto quindi, di nuovo, io voto statico.

+0

@Cody C: Ma come si fa a rispondere alla domanda "Devo istanziare questo oggetto solo per chiamare questa funzione?"? – jason

+1

IMO è solo questione di "Ho bisogno di un oggetto con stato se voglio usare questa funzionalità?" Se sto solo istanziando un oggetto per fare una semplice funzione, allora quella risposta è tipicamente no. –

+1

L'esempio in questione è 'private', quindi non sarebbe una considerazione in questo caso (sarebbe solo se fosse' public'). L'unica considerazione in questo caso è quella relativa alle prestazioni. – awe

8

Ci dovrebbe essere un leggero miglioramento delle prestazioni se dichiarate il metodo statico, perché il compilatore emetterà un'istruzione call anziché callvirt.

Ma come gli altri ha detto, dovrebbe essere statico in ogni caso, dal momento che non è legato ad una specifica istanza

0

Credo che il compilatore non ottimizzare questo in un metodo statico. C'è un miglioramento delle prestazioni poiché il puntatore non dovrà essere controllato per vedere se è nullo in fase di runtime. Dai uno sguardo allo FXCop rule come riferimento.

1

Il compilatore probabilmente prenderà in considerazione questo quando inserisce il codice "JIT" perché è così breve e se lo fa allora sarà probabilmente in grado di ottimizzare qualsiasi riferimento al parametro non utilizzato. Ma non puoi fare affidamento su nulla di tutto ciò.

È ancora necessario creare un oggetto per richiamarlo a meno che non lo si renda statico che ha un overhead molto più grande in ogni caso se non ne è necessario uno per altri motivi.

+0

Hai già l'oggetto ('questo') come nell'esempio per un metodo' private'. – awe

-5

spero che sia necessario definire la differenza tra metodo statico e metodo non statico. Qui sto postando poche semplici linee di codice per visualizzare la differenza concettuale.

public class StaticVsNonStatic 
{ 
    public string NonStaticMethod() //non-static 
    { 

     return "I am the Non-Static Method"; 

    } 

    static public string StaticMethod() //static 
    { 

     return "I am Static Method"; 
    } 

} 

Ora consente di creare una pagina di aspx provare ad accedere a questi 2 metodi definiti nella classe.

public partial class StaticVsNonStatic_StaticVsNonWorkplace : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 

     StaticVsNonStatic objStaticVsNonStatic = new StaticVsNonStatic(); 
     lblDisplayNS.Text = objStaticVsNonStatic.NonStaticMethod(); //Non Static 
     lblDisplayS.Text = StaticVsNonStatic.StaticMethod(); //Static and called without object 
    } 
} 

Grazie e per favore pubblica i vostri commenti.

migliori saluti, Pritom Nandy [Bangladesh]

+2

Elad chiaramente sa già come chiamare un metodo statico. Mentre inizi a rispondere alle domande su questo sito, ti suggerisco di cercare domande che non hanno ancora una risposta accettata. Si può dire perché, quando si cercano le domande, il numero di risposte è giallo se c'è una risposta accettata e bianco se non lo è. C'è uno sfondo rosso se nessuno ha ancora provato a rispondere alla domanda, quali sono i migliori da guardare. Benvenuto in StackOverflow :) –

2

I membri che non accedono ai dati di istanza o chiamano metodi di istanza può essere contrassegnato come static (Shared in Visual Basic). Dopo aver contrassegnato i metodi come statici, il compilatore invierà i siti di chiamata non virtuali a questi membri. L'emissione di siti di chiamate non virtuali impedirà un controllo in fase di esecuzione per ogni chiamata che si assicura che il puntatore dell'oggetto corrente non sia nullo. Ciò può ottenere un guadagno di prestazioni misurabile per un codice sensibile alle prestazioni. In alcuni casi, l'impossibilità di accedere all'istanza dell'oggetto corrente rappresenta un problema di correttezza.

3

Vede qualche vantaggio nel modificare la firma del metodo in statico?

tre vantaggi:

  1. Fare metodi statici apolidi aiuta documento e chiarire il loro scopo. Altrimenti, uno è incline a preoccuparsi solo di quale stato misterioso dipende il metodo?

  2. Il metodo statico può essere chiamato da un altro codice statico, quindi è potenzialmente più utile.

  3. Le chiamate al metodo statico hanno un sovraccarico di runtime inferiore rispetto a quelle di istanza. Il compilatore non può eseguire questa trasformazione automaticamente: uno dei motivi è perché influirebbe sull'utilizzo di null.È necessario chiamare il metodo su un riferimento null per fallire con una NullReferenceException, anche se non esiste uno stato di istanza utilizzato all'interno del metodo.

Problemi correlati