2011-06-02 55 views
25

Con un trozo de código como este, el compilador se queja de c.MyProperty:Reparando el 'Uso de la variable local no asignada' con una asignación nula. ¿Por qué?

MyClass c; 

try { throw new Exception(); } 
catch (Exception) { } 

c.MyProperty = 2; // "Use of unassigned local variable 'c'". 

Sin embargo, no se queja si asigna un null a c de inicialización:

MyClass c = null; 

try { throw new Exception(); } 
catch (Exception) { } 

c.MyProperty = 2; // no complains this time. 

Así que, ¿por qué ¿este trabajo? Si c no tiene asignado un null y el compilador lo permite hipotéticamente, ¿no se arrojaría la misma excepción al c.MyProperty, Referencia del objeto no establecida en una instancia de un objeto?

+0

Hmm, eso es interesante, creo que ha de ser a pesar de que este código (segunda versión) seguiría siendo una excepción en tiempo de ejecución .. lo más probable es sólo una cuestión de Visual Studio que no está recogiendo la asignación nula - Justo una adivinanza ? –

+1

Eche un vistazo a http://stackoverflow.com/questions/4770426/non-initialized-vs-null-values-of-reference-types – Haplo

+1

muy agradable y elegante pregunta – user1451111

Respuesta

53

Cuando asigna null a la variable que está diciendo al compilador que retroceda porque lo conoce mejor que él, por lo que no debe quejarse de esto.

Esto probablemente se deba al hecho de que la asignación de null se considera que implica una acción explícita del desarrollador.

+2

Aunque eso me hizo reír, todavía estoy no más cerca de una respuesta. –

+13

@Andreas: esta es la respuesta real, esta es la razón por la que está permitido. C# te permitirá ** dispararte ** intencionalmente en el pie. Simplemente no te dejará hacerlo sin intención. –

+0

Aunque la forma en que respondí fue para agregar algo de humor a mi opinión, realmente creo que esta puede ser la razón por la cual el compilador deja de quejarse, por lo que es una respuesta válida incluso si al final del día no es la correcta. –

1

Piénselo de esta manera, el compilador no le dice que arrojará una referencia nula y, por lo tanto, no puede compilar, sino que no se cumple una de las condiciones que se requieren para la compilación. es decir, que debe asignarse definitivamente.

De acuerdo con la hipótesis nula spec es AC# literal: "El null-literal se puede convertir implícitamente a un tipo de referencia o tipo anulable"

Así como en términos de asignaciones: (tomada de la especificación)

de inicio de la cita tomada de la especificación

5.3.3 normas precisas para determinar la asignación definitiva con el fin de determinar que cada variable utilizada se asignaron claramente, el compilador debe usar un proceso que sea equivalente al descrito en esta sección.

El compilador procesa el cuerpo de cada miembro de la función que tiene una o más variables inicialmente no asignadas. Para cada variable v inicialmente sin asignar, el compilador determina un estado de asignación definitiva para v en cada uno de los siguientes puntos en el elemento de función:

· Al comienzo de cada declaración

· En el punto final (§ 8.1) de cada declaración

· en cada arco que transfiere el control a otro estado de cuenta o al punto final de una instrucción

· al comienzo de cada expresión

· en Al final de cada expresión

Fin de la cita

Así que, aunque no válida no está realmente apuntando a un objeto en la memoria, no cumple con los requisitos de ser definitivamente asignado y es por eso que el compilador lo permite.

0

Esto es porque el C# especificación Language v 4.0 sección 1.6.6.2 "cuerpo Método y variables locales" establece lo siguiente:.

Un cuerpo método puede declarar variables que son específicas de la invocación del método . Tales variables se llaman variables locales.

[omitido]

C# requiere una variable local para ser definitivamente asignado antes de poder obtener su valor.

Esto es para evitar que te pegues un tiro en el pie, como Binary Worrier claramente señaló.

0

La razón de esta excepción es que no se ha asignado un valor por defecto de la variable de ejemplo

if (Request.Files != null && Request.Files.Count > 0) 
      { 
       Image = Request.Files.AllKeys[0]; 
      } 
var stream = new FileStream(Image,FileMode.Open); 

ahora la variable de imagen dará error del compilador

El uso de variable local no asignada ' Imagen '

Esto se debe a la razón de que existe la posibilidad de que la condición se haga realidad y el control nunca llegue a saber qué la variable de imagen es. así que coloque un bloque else o asigne un valor predeterminado como se muestra a continuación.

string Image = ""; 
if (Request.Files != null && Request.Files.Count > 0) 
      { 
       Image = Request.Files.AllKeys[0]; 
      } 
var stream = new FileStream(Image,FileMode.Open); 
Cuestiones relacionadas