Pregunta

He notado algo peculiar sobre Visual Studio. Primero, intente escribir esto (C #) en algún lugar de una función:

class Foo  
{  
    public void Bar()  
    {  
        string s;
        int i = s.Length;
    }
}

Ahora, de inmediato marcará las s en s.Length como un error, diciendo " Uso de la variable local no asignada 's' " ;. Por otro lado, prueba este código:

class Foo  
{  
    private string s;
    public void Bar()  
    {  
        int i = s.Length;
    }
}

Se compilará y subrayará s en cadena privada s con una advertencia que dice que " Field 'Foo.s' nunca se asigna a, y siempre tendrá su valor predeterminado nulo " ;.

Ahora, si VS es tan inteligente y sabe que s siempre será nulo, ¿por qué no es un error obtener su longitud en el segundo ejemplo? Mi conjetura original era: "Solo da un error de compilación si el compilador simplemente no puede completar su trabajo. Dado que el código técnicamente se ejecuta siempre y cuando nunca llame a Bar (), es solo una advertencia. Excepto que la explicación es invalidada por el primer ejemplo. Aún puede ejecutar el código sin error siempre que nunca llame a Bar (). Entonces, ¿qué da? ¿Solo un descuido, o me estoy perdiendo algo?

¿Fue útil?

Solución

El primer ejemplo (el error) es un ejemplo de seguimiento de asignación definida y eso solo se aplica a las variables locales. Debido al contexto limitado, el compilador tiene un control hermético sobre esta situación. Tenga en cuenta que s no es nulo, no está definido.

En el segundo ejemplo, s es un campo (y su valor predeterminado es nulo). No hay error de compilación, pero siempre se detectará en tiempo de ejecución. Este caso particular podría quedar atrapado, pero este tipo de error en general no es detectable por el compilador.
Por ejemplo, puede agregar un método Bar2 () que asigna una cadena a s pero lo llama más tarde que Bar () , o no en todos. Eso eliminaría la advertencia pero no el error de tiempo de ejecución.

Así es por diseño.

Otros consejos

Para el segundo ejemplo, el código es válido, es posible que no se ejecute correctamente. Aquí hay varios casos en los que este programa podría ejecutarse con éxito "

  • El compilador no es 100% correcto. Es posible para " s " tener un valor no nulo si una instancia se modifica mediante reflexión.
  • El programa puede ejecutarse sin error si el método Bar nunca se llama
  • Este programa podría ser un programa de prueba que está activando una NullReferenceException por razones de prueba

La única suposición que puedo hacer es que en el segundo ejemplo, s podría cambiarse mediante reflexión (usando BindingFlags.Private para acceder al miembro privado).

En la primera muestra, s es una variable local y el compilador puede comprobar fácilmente que la variable s no se asignó antes de su uso.

En el segundo, s es una variable global y es posible que se haya inicializado en otro lugar de una clase.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top