2010-10-11 12 views
42

En C#, ¿es necesario asignar una variable de objeto a null si ha terminado de usarlo, incluso cuando salga de alcance de todos modos?C#: ¿las variables de objeto deben asignarse a nulo?

+1

posible duplicado de [Configuración de objetos en Null/Nada después de su uso en .NET] (http://stackoverflow.com/questions/2785/setting-objects-to-null-nothing-after-use-in-net) – nawfal

Respuesta

37

No, y que de hecho podría ser peligroso y propenso a errores (considere la posibilidad de que alguien intente usarlo más adelante, sin darse cuenta de que se ha establecido en nulo). Solo configure algo como nulo si hay una razón lógica para establecerlo como nulo.

26

Lo que importa más IMO es llamar a Dispose en los objetos que implementan IDisposable.

Aparte de eso, asignar nulo a las variables de referencia solo significa que está indicando explícitamente el fin del ámbito - la mayoría de las veces, es solo una instrucción temprana (por ejemplo, variables locales en el cuerpo del método) - con era de compilador/Optimizaciones JIT, es bastante posible que el tiempo de ejecución haga lo mismo, por lo que realmente no obtienes nada. En algunos casos, como variables estáticas, etc. (cuyo alcance es el nivel de aplicación), debe asignar la variable a nulo si ya no está utilizando, de modo que el objeto obtendrá basura recolectada.

+2

¿Dice que el recolector de basura buscará si una variable es nula para decidir si recolectar basura? Pensé que era solo si todavía estaba vivo/en el alcance. –

+6

Esta presentación PowerPoint http://download.microsoft.com/download/e/2/1/e216b4ce-1417-41af-863d-ec15f2d31b59/DEV490.ppt, deslice 30 en adelante, lo que muestra el JIT/GC hacer juntos. Significa que la asignación nula es particularmente inútil. –

+0

@Damien_The_Unbeliever - ¡un buen recurso! gracias por eso. @Craig, en realidad estaba tratando de decir que es muy posible que GC considere un objeto como basura, incluso si no está * aparentemente * fuera del alcance: lo único que importa es que si se utiliza la referencia o no. Por lo tanto, es bastante posible que el objeto pueda obtener basura recolectada incluso cuando el método de instancia se está ejecutando. Ver este excelente artículo: http://blogs.msdn.com/b/oldnewthing/archive/2010/08/10/10048149.aspx – VinayC

23

¿Debe apagar su automóvil antes de empujarlo hacia el lago?
No. Es un error común, pero no hace ninguna diferencia. No está configurando el objeto como nulo, solo una referencia - el objeto aún está en la memoria y aún debe ser recolectado por el recolector de elementos no utilizados.

4

No. Cuando se trata de variables locales, no hace ninguna diferencia si tiene una referencia al objeto o no, lo que importa es si la referencia se usará o no.

Poner una asignación nula adicional en el código no perjudica mucho el rendimiento, y no afecta en absoluto la gestión de memoria, pero agregará instrucciones no motivadas al código que lo hace menos legible.

El recolector de basura sabe cuándo se utiliza la referencia la última vez en el código, por lo que puede recopilar el objeto tan pronto como ya no se necesite.

Ejemplo:

{ 
    // Create an object 
    StringBuilder b = new StringBuilder(); 
    b.Append("asdf"); 
    // Here is the last use of the object: 
    string x = b.ToString(); 
    // From this point the object can be collected whenever the GC feels like it 
    // If you assign a null reference to the variable here is irrelevant 
    b = null; 
} 
+0

¿El GC realmente sabe qué código se está ejecutando? ¿No es solo hacer un análisis (estático) de la pila y seguir todas las referencias? –

+0

@ OlivierJacot-Descombes: No sabe qué variables usa el código cuando se realiza la recolección de elementos no utilizados. Puede probar esto asignando varias matrices enormes una detrás de otra y asignándolas a las variables locales.Las primeras matrices se recopilarán para hacer espacio para las últimas, aunque hay variables en la pila que tienen referencias a ellas. – Guffa

+0

+1. Tienes razón. Después de leer la página 35 de la presentación de PPT mencionada por Damien_The_Unbeliever, debo estar de acuerdo con usted. –

11

Asignación a nula es generalmente una mala idea:

  1. Conceptualmente, es sólo inútil.
  2. Con muchas variables, puede tener suficientes asignaciones adicionales para anular que aumenta apreciablemente el tamaño del método. Cuanto más largo es el código fuente de algo, más esfuerzo mental se necesita para leerlo (incluso si gran parte de él es solo material que se puede filtrar) y más fácil es detectar un error. Haga que el código sea más detallado de lo necesario solo cuando hacerlo lo haga más comprensible.
  3. Es posible que su asignación nula no se optimice. En ese caso, es posible que el código compilado no realice la desasignación real hasta que llegue a esa asignación nula, mientras que en la mayoría de los casos una vez que la variable no hará nada más que caer fuera del alcance (y algunas veces incluso antes) puede ser desasignado Por lo tanto, puede tener un impacto de rendimiento muy leve.

La única vez que asignaría algo a nulo para "borrar" una variable que ya no se usará, en lugar de porque nulo es realmente un valor que explícitamente quiero asignar, está en uno de los dos casos posibles :

  1. Es un miembro de un objeto posiblemente de larga vida, ya no será utilizado por ese objeto, y es de un tamaño considerable. Aquí asignar a null es una optimización.
  2. es miembro de un objeto, posiblemente, de larga vida, ya no será utilizado por ese objeto, y por lo tanto se ha dispuesto para liberar sus recursos. Aquí asignar a null es una cuestión de seguridad, ya que puede ser más fácil encontrar un caso en el que accidentalmente se usa un objeto nulo que cuando uno usa accidentalmente un objeto dispuesto.

Ninguno de estos casos se aplica a las variables locales, solo a los miembros, y ambos son raros.

+0

Su segundo caso tiene sentido. Seguir una excepción de referencia nula es más fácil que rastrear un objeto medio dispuesto – rolls

+1

@rolls sí, especialmente dado que el efecto de usar un objeto tan obsoleto puede estar muy lejos del bit equivocado de código. –

0

Me gustaría agregar que AFAIK era solo un patrón válido para una versión de punto de Visual Basic, e incluso que era algo discutible. (IIRC que era sólo para objetos DAO.)

15

La mayor parte de estas respuestas tienen la respuesta correcta, pero por las razones equivocadas.

Si se trata de una variable local, la variable se caerá la pila al final del método y por lo tanto el objeto que estaba señalando tendrá uno menos de referencia. Si esa variable era la única referencia al objeto, entonces el objeto está disponible para GC.

Si establece la variable como nula (y muchos de los que sí aprendieron a hacerlo al final del método), podría terminar ampliando el tiempo que el objeto permanece en la memoria porque el CLR creerá que el objeto no se puede recopilar hasta el final del método porque ve una referencia de código al objeto muy por debajo. Sin embargo, si omite la configuración de nulo, el CLR puede determinar que no aparecen más llamadas para el objeto después de un cierto punto en el código y, aunque el método aún no se haya completado, el GC puede recopilar el objeto.

Cuestiones relacionadas