Cambios problemáticos en Visual C# 2008
Actualización: Julio de 2008
Cambios problemáticos en Visual C# 2008 Service Pack 1
En la tabla siguiente se hacen una lista de todos los cambios problemáticos en Visual C# 2008 Service Pack 1 que pueden afectar a las aplicaciones creadas en la versión de lanzamiento original de Visual C# 2008 o en Visual C# 2005.
Número de cambio |
Category |
Problema |
Descripción |
---|---|---|---|
1 |
Resolución de sobrecarga |
La inferencia de tipos está ahora incluida en las matrices de tipos de puntero en la resolución de sobrecarga de los métodos. |
En Visual C# 2008 y versiones anteriores, la inferencia de tipos provoca la exclusión de las matrices de tipos de puntero del proceso de resolución de sobrecarga de los métodos. En el código siguiente, el compilador de Visual C# 2005 selecciona la versión no genérica de Test porque la versión genérica de Test no se tiene en cuenta debido a su parámetro de tipo int*[]. En Visual C# 2008, se selecciona la versión genérica de Test.
|
2 |
Indizadores |
Ahora el compilador genera el error CS0466 para los indizadores y las propiedades además de generarlo para los métodos. |
En la versión de lanzamiento original de Visual C# 2008 y versiones anteriores, es posible definir una implementación explícita de un indizador en el que la implementación tiene un parámetro params pero la definición de interfaz no. Esta construcción es contraria a la especificación. En Visual C# 2008 SP1, esta construcción genera el Error del compilador CS0466, como se muestra en el código siguiente.
} |
3 |
Tipos que aceptan valores NULL y expresiones ?? |
El compilador evalúa ahora correctamente las expresiones en las que las variables que aceptan valores NULL se comparan consigo mismas. |
En la versión de lanzamiento original de Visual C# 2008, el código siguiente compila y genera "false" en tiempo de ejecución. En Visual C# 2008 Service Pack 1, se genera la Advertencia del compilador (nivel 3) CS1718 y se produce "true" como resultado.
|
4 |
try-finally en iteradores |
Ha cambiado la ejecución de bloques finally anidados de los iteradores con instrucciones break. |
En la versión de lanzamiento original de Visual C# 2008, el código siguiente ejecuta el bloque finally exterior dos veces. En Visual C# 2008 SP1, el bloque finally exterior se ejecuta una vez.
|
5 |
Árboles de expresión |
Ya no se produce la conversión boxing incorrecta de expresiones de método en árboles de expresión. |
En la versión de lanzamiento original de Visual C# 2008, el código siguiente genera 7, 0. La línea Console.WriteLine(e.Compile()(default(T))); produce cero como resultado porque se aplica una conversión boxing incorrecta a S. En Visual C# 2008 SP1, no se produce ninguna conversión boxing y el programa produce 7, 7 como resultado.
|
6 |
Inicializadores de objeto |
Se ha corregido la inicialización de los tipos de valor en los inicializadores de objeto. |
En la versión de lanzamiento original de Visual C# 2008, la variable local b del ejemplo siguiente no se inicializa correctamente y su miembro X tiene un valor de cero. En Visual C# 2008 SP1, S.X se inicializa correctamente en 1 en ambas expresiones new.
|
7 |
Conversiones de tipo |
Los literales null ya no se pueden convertir en valores enum. |
En la versión de lanzamiento original de Visual C# 2008, en algunos casos se permite convertir los literales null en valores enum. En Visual C# 2008 SP1, se generan el Error del compilador CS1502 y el Error del compilador CS1503 si se intenta esta operación, tal como se muestra en el ejemplo siguiente.
|
8 |
Árboles de expresión |
El árbol de expresión no válido produce ahora la excepción correcta. |
En la versión de lanzamiento original de Visual C# 2008, un árbol de expresión que contiene una llamada a un método que no está incluido en el tipo especificado produce System.Security.VerificationException. En Visual C# 2008 SP1, se produce System.ArgumentException, como se muestra en el código siguiente.
|
9 |
Atributos |
CharSet.Unicode se propaga ahora a los tipos de aplicación auxiliar que C# genera para los campos de matriz fija. |
El compilador de C# genera tipos de aplicación auxiliar para encapsular las matrices fijas. En la versión de lanzamiento original de Visual C# 2008 y versiones anteriores, el diseño de la matriz es siempre ANSI, aunque el atributo StructLayout especifique CharSet.Unicode. En el código fuente de C# no había manera de cambiar este diseño. En Visual C# 2008 SP1, se utiliza cualquier valor de CharSet que se especifique en el atributo StructLayout para construir la clase de aplicación auxiliar, tal como se muestra en el código siguiente.
|
10 |
Comprobación de desbordamiento |
stackalloc realiza ahora una comprobación de desbordamiento. |
En la versión de lanzamiento original de Visual C# 2008 es posible que una asignación stackalloc produzca un error sin producir una excepción. Esto se debe a una instrucción mul no comprobada en el lenguaje intermedio de Microsoft (MSIL) generado cuando la longitud de la matriz se multiplica por el tamaño de cada elemento. En Visual C# 2008 SP1, se genera una instrucción mul.ovf en lugar de mul, de modo que los desbordamientos generan System.OverflowException cuando se intenta realizar la asignación en tiempo de ejecución.
|
11 |
Operadores de consulta estándar |
Las consultas en colecciones no genéricas utilizan ahora semántica de conversión de tipos de C# estándar. |
En las expresiones de consulta LINQ en colecciones no genéricas como System.Collections.ArrayList, el compilador vuelve a escribir la cláusula from de la consulta para incluir una llamada al operador Cast<T>. Cast<T> convierte todos los tipos de elemento al tipo especificado en la cláusula from de la consulta. Además, en la versión de lanzamiento original de Visual C# 2008, el operador Cast<T> también realiza algunas conversiones de tipo de valor y conversiones definidas por el usuario. Sin embargo, estas conversiones se realizan utilizando la clase System.Convert en lugar de la semántica de C# estándar. Estas conversiones también producen importantes problemas de rendimiento en ciertos escenarios. En Visual C# 2008 SP1, se modifica el operador Cast<T> para producir una excepción InvalidCastException para el tipo de valor numérico y las conversiones definidas por el usuario. Este cambio elimina tanto la semántica de conversión de tipo no estándar de C# y el problema de rendimiento. Este cambio se muestra en el siguiente ejemplo.
|
Cambios problemáticos en la versión de lanzamiento original de Visual C# 2008
En la tabla siguiente se enumeran todos los cambios problemáticos de la versión de lanzamiento original de Visual C# 2008 que podrían impedir la compilación de una aplicación creada en Visual C# 2005 o que podrían cambiar su comportamiento en tiempo de ejecución.
Número de cambio |
Category |
Problema |
Descripción |
---|---|---|---|
12 |
Conversiones de tipo |
Ahora se permite la conversión a enum de cualquier expresión constante con un valor de cero. |
Un literal 0 se puede convertir implícitamente a cualquier tipo de enumeración. En Visual C# 2005 y versiones anteriores del compilador, existen también algunas expresiones constantes que se evalúan como 0 que se pueden convertir implícitamente en cualquier tipo de enumeración, pero la regla que determina cuáles de estas expresiones se pueden convertir no está clara. En Visual C# 2008, todas las expresiones constantes que son iguales a 0 se pueden convertir implícitamente en cualquier tipo de enumeración. Esto podría producir algunos cambios en el comportamiento del código existente, como la resolución de sobrecarga de los métodos que se basa en la ausencia de esta conversión implícita. El código siguiente compila correctamente en Visual C# 2005 y compiladores anteriores, ya que resuelve la llamada al método en el valor short solo con la sobrecarga de tipo entero. En Visual C# 2008, esta llamada es ambigua porque el valor short también se puede convertir implícitamente en E. En Visual C# 2008, el comportamiento cambia para permitir la conversión de cualquier expresión constante que se evalúe como cero.
|
13 |
Atributos |
Ahora el error se produce cuando el mismo atributo TypeForwardedTo está presente dos veces en un ensamblado. |
En Visual C# 2005, no se produce ningún error si un ensamblado contiene dos atributos System.Runtime.CompilerServices.TypeForwardedTo que tienen como destino el mismo tipo. En Visual C# 2008, se genera el Error del compilador CS0739, como se muestra en el ejemplo siguiente.
} |
14 |
Errores de tipo |
Se ha agregado una nueva advertencia sobre el uso de un miembro de tipo de referencia en una estructura. |
Las reglas de asignación definitiva de las estructuras requieren que la estructura se establezca en una instancia existente de su tipo o que cada uno de sus miembros se asigne a ella antes de crear la referencia. En Visual C# 2005, no se produce ninguna advertencia ni error cuando se utiliza un miembro de tipo de referencia sin asignar de una estructura. En Visual C# 2008, se genera el Advertencia del compilador (nivel 1) CS1060, como se muestra en el ejemplo siguiente.
|
15 |
Comprobación de desbordamiento |
Se ha corregido la comprobación del intervalo en los tipos decimales const. |
En Visual C# 2005, al convertir los tipos decimales const, la comprobación del intervalo no siempre es correcta y se pueden provocar errores incorrectos del compilador. En Visual C# 2008, el código siguiente genera el error correcto: Error del compilador CS0031.
|
16 |
Comprobación de desbordamiento |
Las conversiones fuera de los límites a long generan ahora el error correcto del compilador. |
En Visual C# 2005, el código siguiente no genera ningún error del compilador. En Visual C# 2008, genera el Error del compilador CS0031.
|
17 |
Búferes de tamaño fijo |
El acceso a un búfer de tamaño fijo en una estructura no segura antes de asignar un valor al búfer genera ahora un error del compilador. |
Las reglas de asignación definitiva para los punteros no seguros requieren que se establezca el puntero antes de eliminar las referencias del puntero. En Visual C# 2005, cuando una estructura no segura contiene un puntero a una matriz, el acceso al puntero antes de asignarle un valor, no generaba ningún error del compilador. En Visual C# 2008, genera el Error del compilador CS0165, como se muestra en el código siguiente.
|
18 |
Los efectos secundarios se conservan ahora en las expresiones de uso combinado de NULL. |
Asignación definitiva y el operador ??. |
En Visual C# 2005, en ciertos escenarios, no se conservan los efectos secundarios en el lado izquierdo de una expresión de uso combinado de NULL. En estos casos, la segunda instrucción Console.WriteLine del ejemplo siguiente genera un error incorrecto del compilador que indica que no se ha asignado b. En Visual C# 2008, el mismo código compila correctamente sin ningún error.
} |
19 |
try-finally en iteradores |
Ahora el bloque finally se ejecuta cuando un iterador del bloque try escapa con continue o goto. |
En Visual C# 2005, en una construcción try-finally, cuando un control sale de un bloque de iteradores en el bloque try mediante una instrucción goto o continue, el bloque finally no se ejecuta. En Visual C# 2008, en estos casos se ejecuta el bloque finally.
} |
20 |
Clases base e interfaces |
La construcción de clases omite ahora las implementaciones explícitas de los mismos miembros de interfaz en las clases base. |
En Visual C# 2005, cuando una clase no proporciona una implementación para un miembro de interfaz, el compilador sustituye las implementaciones de la clase base aunque se declaren como implementaciones explícitas de interfaz. Este comportamiento no cumple con la especificación de la Asociación europea de fabricantes de informática (ECMA). Visual C# 2008 implementa correctamente la especificación. En el ejemplo siguiente, Visual C# 2005 imprime "B.Test". Visual C# 2008 imprime correctamente "A.Test" y omite el método Test de la clase B porque es una implementación de interfaz explícita.
} |
21 |
Atributos |
El uso de un miembro obsoleto genera ahora una advertencia del compilador. |
Puede marcar los métodos con el atributo Obsolete para producir errores o advertencias en tiempo de compilación si se invocan los métodos. Al incluir este atributo en métodos virtuales, se debe colocar en el método base. Si el atributo Obsolete se incluye en un método de invalidación, no producirá errores ni advertencias del compilador al invocar el método. En Visual C# 2005, el compilador permitía incluir el atributo Obsolete en un método de invalidación aunque no tenía ningún efecto en este caso. En Visual C# 2008, se produce la advertencia del compilador Advertencia del compilador (nivel 1) CS0809, "El miembro obsoleto 'A.Filename' invalida el miembro no obsoleto 'Error.Filename'". En el ejemplo siguiente se genera esta advertencia:
|
22 |
Errores de compilación |
El uso de la opción del compilador /pdb sin /debug genera ahora un error. |
En Visual C# 2005, no se muestra ninguna advertencia ni error al especificar la opción /pdb pero no la opción /debug. Visual C# solo crea una versión de lanzamiento sin generar el archivo .pdb. En la versión de lanzamiento original de Visual C# 2008, si especifica /pdb sin especificar también /debug, el compilador muestra el Error del compilador CS2036. |
23 |
Errores de tipo |
Ahora se genera un error cuando una condición switch es void. |
En Visual C# 2005, no se genera ningún error cuando se utiliza una invocación de método void en una instrucción switch. En Visual C# 2008, se genera el Error del compilador CS0151.
} |
24 |
Comprobación de desbordamiento |
Ahora las conversiones de decimal constante a entero generan un error diferente del compilador. |
En Visual C# 2005, el código siguiente genera el Error del compilador CS0133: "La expresión que se asigne a 'b' debe ser constante".
En Visual C# 2008, se genera el Error del compilador CS0031: "El valor constante '256M' no se puede convertir en 'byte'". Observe que el error se genera aunque se aplique el modificador unchecked. |
25 |
Expresiones constantes |
La especificación se cumple mejor en lo que respecta a las expresiones constantes. |
En Visual C# 2008, se han corregido varios problemas por los que Visual C# 2005 permitía incorrectamente operadores y variables en expresiones constantes. En Visual C# 2005, el código siguiente compila sin errores. En Visual C# 2008, se generan el Error del compilador CS0165, la Advertencia del compilador (nivel 1) CS0184 y la Advertencia del compilador (nivel 3) CS1718:
|
26 |
Errores de tipo |
Ahora se genera un error cuando se utiliza un tipo estático como parámetro en un delegado o en una expresión lambda. |
En Visual C# 2005, no se genera ningún error si se utiliza un tipo estático como parámetro de un delegado o un método anónimo. Los tipos estáticos no se pueden utilizar como tipos de parámetros de método porque no se pueden crear instancias de ellos. La versión de Visual C# 2005 del compilador permite los tipos estáticos como tipos de parámetro dentro de delegados y declaraciones de método anónimo. Si pasa null como parámetro, se pueden invocar estos delegados. En Visual C# 2008, se genera el Error del compilador CS0721 si se utiliza un tipo estático como parámetro de un delegado o un método anónimo, como se muestra en el ejemplo siguiente.
} |
27 |
Tipos que aceptan valores NULL y expresiones ?? |
Cuando se convierte una constante en un tipo que acepta valores NULL antes de asignarlo a un tipo que acepta valores NULL (más amplio), no se produce ninguna advertencia. |
En Visual C# 2005, el código siguiente genera la Advertencia del compilador (nivel 3) CS0219. En Visual C# 2008, no se genera ninguna advertencia.
|
28 |
Resolución de sobrecarga |
Ahora se genera un error cuando se produce una resolución de sobrecarga ambigua en métodos anónimos. |
El compilador debe resolver las invocaciones de método en métodos sobrecargados para determinar qué sobrecarga concreta se debe invocar. Cuando se infiere parcialmente el tipo de parámetro de una invocación, puede que la sobrecarga concreta que se debe invocar resulte ambigua. Esto provoca un error del compilador. Cuando se pasa un método anónimo como parámetro de un delegado, se infiere parcialmente el tipo de delegado del método anónimo. Esto puede provocar ambigüedad cuando el compilador selecciona la sobrecarga correcta. En Visual C# 2005, el compilador no siempre genera un error cuando no existe una única sobrecarga preferible para un método anónimo. En Visual C# 2008, se genera el Error del compilador CS0121, como se muestra en el ejemplo siguiente.
|
29 |
Errores de tipo |
Ahora se genera un error si declara una matriz de punteros a tipos administrados. |
No se permiten los punteros no seguros a tipos de referencia; generan errores del compilador. En Visual C# 2005, es posible declarar una matriz de punteros a tipos administrados. En Visual C# 2008, se genera el Error del compilador CS0208: "No se puede adquirir la dirección, obtener el tamaño ni declarar un puntero a un tipo administrado ('T')".
} |
30 |
Resolución de sobrecarga |
Ahora se genera una advertencia cuando los métodos del candidato de resolución de sobrecarga varían solo en ref o out. |
En Visual C# 2005, cuando el compilador de C# realiza la resolución de sobrecarga en tipos genéricos, no comprueba si los argumentos de tipo harán que los métodos de candidato varíen solo en ref o out. Como resultado, la selección del método queda a cargo de Common Language Runtime (CLR) en tiempo de ejecución, que simplemente selecciona el primer método de la lista. En Visual C# 2008, se genera la Advertencia del compilador (nivel 1) CS1956 cuando el compilador detecta que dos métodos de candidato para la resolución de sobrecarga variarán solo en ref o out. Esta condición se muestra en el siguiente ejemplo.
} |
31 |
Tipos que aceptan valores NULL y expresiones ?? |
Una expresión de uso combinado de NULL con NULL en el lado izquierdo ya no se evalúa como una constante NULL. |
En Visual C# 2005, una expresión de uso combinado de NULL con NULL en el lado izquierdo se evalúa como una constante NULL. En Visual C# 2008, esto ya no sucede así. En algunos casos, el comportamiento de Visual C# 2005 permite que las variables se traten de manera incorrecta como variables asignadas definitivamente. El código siguiente compila y se ejecuta sin error en Visual C# 2005, pero en Visual C# 2008, se genera el Error del compilador CS0165: "Uso de la variable local no asignada 'x'".
|
Vea también
Otros recursos
Historial de cambios
Fecha |
Historial |
Motivo |
---|---|---|
Julio de 2008 |
Se ha agregado un tema. |
Cambio de características de SP1. |