2010-03-15 13 views
34

Qual è la procedura migliore per gestire gli oggetti in for o foreach loop? Dovremmo creare un oggetto fuori dai loop e ricrearlo di nuovo (usando new ...) o crearne uno nuovo per ogni iterazione del ciclo?
Esempio:Procedura consigliata per la creazione di oggetti utilizzati in/foreach loop

foreach(var a in collection) 
{ 
    SomeClass sc = new SomeClass(); 
    sc.id = a; 
    sc.Insert(); 
} 

o

SomeClass sc = null; 
foreach(var a in collection) 
{ 
    sc = new SomeClass(); 
    sc.id = a; 
    sc.Insert(); 
} 

che è meglio?

risposta

67

La prima è migliore poiché trasmette più chiaramente lo scopo previsto della variabile e impedisce che gli errori utilizzino accidentalmente un oggetto al di fuori dell'ambito previsto.

Un motivo per cui si desidera utilizzare il secondo modulo è se si desidera interrompere il ciclo e avere ancora un riferimento all'oggetto che è stato raggiunto l'ultimo ciclo.

Una cattiva ragione per scegliere il secondo modulo è la prestazione. Potrebbe sembrare a prima vista che il secondo metodo utilizza meno risorse o che si sta creando un solo oggetto e riutilizzandolo. Questo non è il caso qui. La dichiarazione ripetuta di una variabile all'interno di un ciclo non consuma risorse aggiuntive o cicli di clock in modo da non ottenere alcun vantaggio in termini di prestazioni dall'estrazione della dichiarazione all'esterno del ciclo.

+3

+1 - gli oggetti devono essere dichiarati solo dove e quando sono necessari. Se hai bisogno di int i in un ciclo for dichiaralo all'interno del ciclo for non nella parte superiore del corpo della funzione. Vedi codice completo :). – JonH

+1

Nella dichiarazione delle variabili .Net si tratta in realtà di metadati del metodo. L'effettiva posizione in cui la variabile viene creata nel codice influisce solo sull'ambito del compilatore ... In altre parole, non vi è alcuna differenza di prestazioni tra questi due esempi. –

+2

C'era una volta, c'erano leggere differenze nell'IL prodotto tra questi due cicli (lo stesso con Java e C++), sebbene non abbastanza da preoccuparsi. Non sono sicuro se gli attuali compilatori lo abbiano modificato o se il CLR ottimizzi l'extra IL via. –

4

Sono sicuro che qualcuno potrebbe eseguire l'analisi MSIL, ma praticamente non c'è alcuna differenza visibile nell'esecuzione o nelle prestazioni. L'unica cosa che stai influenzando è la memorizzazione di un riferimento a un oggetto.

Dico mantieni pulito e semplice; dichiarare la variabile all'interno del ciclo. Ciò fornisce in pratica il principio di apertura/chiusura, in modo da conoscere l'ambito in cui la variabile viene utilizzata e non viene riutilizzata altrove. Nel ciclo successivo, la variabile perde lo scope e viene reinizializzata automaticamente.

1

Penso che non abbia importanza per le prestazioni, ma preferisco il primo. Cerco sempre di mantenere insieme la dichiarazione e l'istanza, se possibile.

+0

'Vai alla definizione 'è molto più utile quando imposta effettivamente l'oggetto anziché dichiararlo. – cjk

3

Si sta creando un nuovo oggetto in ogni iterazione del ciclo in entrambi i casi (poiché si chiama new SomeClass()).

Il precedente approccio chiarisce che sc viene utilizzato solo all'interno del ciclo, il che potrebbe rappresentare un vantaggio dal punto di vista della manutenzione.

0

Vorrei utilizzare il primo, ma per il compilatore è lo stesso, perché il compilatore sposta la dichiarazione delle variabili dai loop. Scommetto che dopo aver compilato il codice sembrerebbe il secondo.

+0

Chiudi. Il secondo produce 2 comandi IL aggiuntivi, ldnull e stloc.n per assegnare null a sc. –

12

Prima di tutto, prendo atto che intendi "creare variabili" quando dici "creare oggetti". I riferimenti dell'oggetto vanno in le variabili, ma non sono le variabili stesse.

Si noti che lo scenario che si descrive introduce una differenza semantica quando il ciclo contiene una funzione anonima e la variabile è una variabile esterna chiusa della funzione anonima. Vedere

http://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/

per i dettagli.

1

Vorrei andare con l'opzione 2 per essere in ordine, per mantenere tutte le dichiarazioni in un unico posto. Si potrebbe dire che gli oggetti "devono essere dichiarati solo dove e quando sono necessari" ma il ciclo probabilmente si troverà nel suo piccolo metodo.

+1

Detto come un programmatore C. – riwalk

Problemi correlati