2010-06-28 20 views
10

En un proyecto de código mixto (VB y C#) nos depuración algún viejo código de Visual Basic así:Nada es igual a String.Empty, null no es igual a String.Empty, ¿qué me falta aquí?

If Request.Params("xxx") <> "" Then 
    'do something 

que considera esto un error que podría ser Request.Params null, en cuyo caso el estado haría' ve convertido en falso, que no era la idea.

Así que pensé. Me acabo de enterar - una vez más - que Nothing de VB y C# 's null no son las mismas cosas y Nothing no es lo mismo que null. De hecho:

if(String.Empty == null)   // in C# this is always false (correct) 
If String.Empty = Nothing Then ' in VB this is always true (????) 

¿Cómo es esto posible? ¿Es esto un problema de compatibilidad con versiones anteriores?

Respuesta

16

Nothing tiene un significado especial en VB para cuerdas. Para comprobar si una cadena de referencia es nulo, es necesario:

If value Is Nothing 

Desde el VB comparison operators documentation:

comparaciones numéricas tratan Nada como 0. Las comparaciones de cadenas tratan Nada como "" (una cadena vacía).

Sospecho que esto es sólo para la compatibilidad con Visual Basic 6 - no es algo que yo sería feliz, si yo fuera un desarrollador VB.

Una comparación de la forma

If value = Nothing 

se compila para una llamada a Microsoft.VisualBasic.CompilerServices.Operators.CompareString que devuelve 0 (es decir igual) si un operando es nulo y el otro está vacía.

+0

Sí, gracias, eso lo entiendo :). Pero la primera parte de tu respuesta es intrigante. Iguales deberían dar una referencia igual a cuando se compara con Nada, ¿no es así? – Abel

+0

Ah, ignora mi comentario anterior. Usted editó mientras tanto. Eso es más parecido, gracias por la referencia. Tampoco estoy tan feliz con eso. ¿Alguna (más) idea sobre la parte "por qué"? Suena muy parecido a Perl: todo es una cadena hasta nuevo aviso. – Abel

+0

@Abel: ¿Qué parte - por qué querían preservar la compatibilidad con pre.NET VB, o por qué pre.NET VB tenía este tipo de comparación? –

1

Usted quiere

If Not String.IsNullOrEmpty(Request.Params("xxx") Then 
    ... 
End If 

O

if (!String.IsNullOrEmpty(Request.Params("xxx")) { 
    ... 
} 
+1

Sí, probablemente. Pero esa no es la pregunta aquí ... La pregunta es por qué la igualdad percibida (en) no es real (en) en VB. Por qué 'Nothing' no es' null', mientras que a menudo lo es. – Abel

+0

Sí, acabo de leer mal, aún así esto ayuda a evitar este problema. = en VB.NET es diferente de == como aclara Jon Skeet (debería ser el aceptado). –

+1

Creo que el punto principal es que en BASIC, la cadena no es un puntero, es solo cero o más caracteres. Por lo tanto, no es posible comparar con NULL. – PauliL

4

En vb6, el valor predeterminado para una variable de cadena era una cadena vacía. Un programador de vb6 que se base en tal comportamiento no sería "peor" que un programador de C que confía en la inicialización cero por defecto de las variables int; ambos comportamientos fueron especificados como parte del lenguaje.

Además, en COM (el marco en el que se basaban las versiones anteriores de VB6), cada vez que se creaba una referencia a una cadena, alguien tenía que deshacerse de ella manualmente. Dado que la cadena más comúnmente utilizada era la cadena vacía, muchos métodos COM están explícitamente documentados con respecto a un puntero nulo como equivalente a una cadena vacía. Esto significa que una función que devuelve una cadena vacía o que pasa una como parámetro de valor o devuelve una puede simplemente pasar un puntero nulo sin tener que asignar nada; el destinatario del puntero nulo no tendrá que desasignar nada.

Dado que los objetos en .net no requieren una desasignación explícita, las ventajas de rendimiento de considerar una referencia nula como una cadena vacía ya no se aplican.No obstante, los métodos que se invocan desde un código que podría esperar un comportamiento similar al de los métodos COM a menudo considerarán que las referencias a cadenas nulas son las mismas que las cadenas vacías.

+0

Consideraciones y pensamientos interesantes, esp. la comparación con COM. Gracias por agregarlo a esta vieja pregunta +1;) – Abel