2010-03-15 10 views
34

¿Cuál es la mejor práctica para tratar con los objetos de los bucles for o foreach? ¿Deberíamos crear un objeto fuera de los bucles y volver a crearlo (usando nuevo ...) o crear uno nuevo para cada iteración de bucle?
Ejemplo:Práctica recomendada para crear objetos utilizados en los bucles for/foreach

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(); 
} 

¿Qué es mejor?

Respuesta

67

La primera forma es mejor, ya que transmite más claramente el alcance previsto de la variable y evita errores al utilizar accidentalmente un objeto fuera del alcance previsto.

Una razón para querer usar el segundo formulario es si quiere salir del bucle y aún tener una referencia al objeto que alcanzó por última vez en el ciclo.

Una mala razón para elegir el segundo formulario es el rendimiento. A primera vista, puede parecer que el segundo método usa menos recursos o que solo está creando un objeto y reutilizándolo. Este no es el caso aquí. La declaración repetida de una variable dentro de un bucle no consume ningún recurso adicional o ciclo de reloj, por lo que no obtiene ningún beneficio de rendimiento si tira de la declaración fuera del bucle.

+3

+1 - los objetos solo deben declararse donde y cuando sean necesarios. Si necesita int i en un ciclo for lo declara dentro del bucle for no en la parte superior del cuerpo de la función. Ver Código Completo :). – JonH

+1

En la declaración de variables .Net es realmente metadatos del método. La ubicación real de donde se crea la variable en el código solo afecta el alcance del compilador ... En otras palabras, no hay diferencia de rendimiento entre estos dos ejemplos. –

+2

Érase una vez, hubo ligeras diferencias en la IL producida entre esos dos bucles (lo mismo con Java y C++), aunque no lo suficiente como para importarle. No estoy seguro si los compiladores actuales han cambiado eso o si el CLR optimiza el IL adicional. –

4

Estoy seguro de que alguien podría impulsar el análisis MSIL, pero prácticamente no hay una diferencia discernible en la ejecución o el rendimiento. Lo único que afecta es el almacenamiento de una referencia de objeto.

Digo mantenlo limpio y simple; declara la variable dentro del bucle. Esto proporciona el principio abierto/cerrado en la práctica, por lo que conoce el alcance con el que se utiliza la variable y no se reutiliza en ningún otro lugar. En el siguiente ciclo, la variable pierde alcance y se reinicializa automáticamente.

1

Creo que no importa el rendimiento, pero prefiero el primero. Siempre trato de mantener la declaración y la instanciación juntas si es posible.

+0

'Ir a definición' es mucho más útil cuando realmente establece el objeto en lugar de declararlo. – cjk

3

Está creando un nuevo objeto en cada iteración de bucle en ambos casos (ya que llama al new SomeClass()).

El primer enfoque deja en claro que sc solo se usa dentro del bucle, lo que podría ser una ventaja desde el punto de vista del mantenimiento.

0

Usaría el primero, pero para el compilador es el mismo, porque el compilador mueve la declaración de variables de los bucles. Apuesto que después de compilar el código se vería como el segundo.

+0

Cerrar. El segundo produce 2 comandos IL adicionales, ldnull y stloc.n para asignar null a sc. –

12

En primer lugar, noto que quiere decir "crear variables" cuando dice "crear objetos". Las referencias de objeto van a en las variables, pero no son las variables mismas.

Tenga en cuenta que el escenario que describe introduce una diferencia semántica cuando el bucle contiene una función anónima y la variable es una variable externa cerrada de la función anónima. Ver

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

para más detalles.

1

Me gustaría ir con la opción 2 para estar ordenado, para mantener todas las declaraciones en un solo lugar. Puede decir que los objetos "solo deben declararse donde y cuando se necesiten" pero su bucle probablemente sea en su propio pequeño método.

+1

Dicho como un programador en C. – riwalk

Cuestiones relacionadas