Documentos de Académico
Documentos de Profesional
Documentos de Cultura
ndice Notas generales Introduccin a las instrucciones Uso de instrucciones condicionales Uso de instrucciones iterativas Uso de instrucciones de salto Tratamiento de excepciones bsicas Lanzamiento de excepciones 1 2 6 15 25 28 39
Instrucciones y excepciones
Instrucciones y excepciones
Notas generales
Objetivo del tema
Ofrecer una introduccin a los contenidos y objetivos del mdulo.
Introduccin a las instrucciones Uso de instrucciones condicionales Use instrucciones iterativas Uso de instrucciones de salto Tratamiento de excepciones bsicas Lanzamiento de excepciones
Explicacin previa
En este mdulo estudiar las instrucciones comunes y las instancias de programacin que se pueden emplear en C#.
Una de las cosas ms importantes a la hora de utilizar un lenguaje de programacin es saber escribir las instrucciones que forman la lgica de un programa en ese lenguaje. Este mdulo explica cmo usar algunas instrucciones comunes, as como el tratamiento de excepciones en C#. En particular, este mdulo muestra cmo lanzar y capturar errores, y cmo emplear bloques try-finally para asegurarse de que una excepcin no hace que el programa se detenga antes de que se elimine el error. Al final de este mdulo, usted ser capaz de: Describir los distintos tipos de instrucciones de control. Usar instrucciones de salto. Usar instrucciones condicionales. Usar instrucciones iterativas. Tratar y lanzar excepciones.
Instrucciones y excepciones
Explicacin previa
Esta seccin ofrece una introduccin a las instrucciones y a los principales tipos de instrucciones que se emplean en C#.
Un programa consiste en una sucesin de instrucciones. En tiempo de ejecucin, estas instrucciones se ejecutan en el orden en que aparecen en el programa, de izquierda a derecha y de arriba a abajo. Al final de esta leccin, usted ser capaz de: Agrupar un conjunto de instrucciones en C#. Usar los distintos tipos de instrucciones disponibles en C#.
Instrucciones y excepciones
Bloques de instrucciones
Objetivo del tema
Explicar cmo agrupar instrucciones en bloques.
Explicacin previa
Un bloque y su bloque padre o pueden tener una variable con el mismo nombre
{{ int i; int i; ... ... {{ int i; int i; ... ... }} }}
Cuando se desarrollan aplicaciones C# es necesario agrupar instrucciones, del mismo modo que se hace en otros lenguajes de programacin. Para ello se emplea la sintaxis de lenguajes como C, C++ y Java, lo que significa que los grupos de instrucciones estn rodeados por llaves: { y }. Para los grupos de instrucciones no se utilizan delimitadores con combinaciones de palabras, como If ... End If de Microsoft Visual Basic.
Instrucciones y excepciones
Sin embargo, es posible declarar variables con el mismo nombre en bloques hermanos. Los bloques hermanos son bloques que pertenecen al mismo bloque padre y estn anidados al mismo nivel, como en el siguiente ejemplo:
{ int i; ... } ... { int i; ... }
Se pueden declarar variables en cualquier punto de un bloque de instrucciones, lo que hace ms sencillo seguir la recomendacin de inicializar una variable en el momento de declararla.
Instrucciones y excepciones
Tipos de instrucciones
Objetivo del tema
Describir los tres tipos de instrucciones comunes que se pueden utilizar en el lenguaje C#.
Instrucciones Condicionales Instrucciones Condicionales Las instrucciones if y switch Las instrucciones if y switch Instrucciones de iteracin Instrucciones de iteracin Las instrucciones while, do, for, y foreach Las instrucciones while, do, for, y foreach Instrucciones de salto Instrucciones de salto Las instrucciones goto, break, y continue Las instrucciones goto, break, y continue
Explicacin previa
La complejidad de la lgica de un programa aumenta a medida que lo hace la complejidad del problema que se intenta resolver con ese programa. Por ello es preciso que el programa tenga control estructurado de flujo, lo que se puede conseguir mediante el uso de instancias o instrucciones de ms alto nivel. Estas instrucciones se pueden agrupar en las siguientes categoras: Instrucciones condicionales Las instrucciones if y switch se conocen como instrucciones condicionales, ya que toman decisiones en funcin del valor de expresiones y ejecutan unos comandos u otros en funcin de las decisiones tomadas. Instrucciones iterativas Las instrucciones while, do, for y foreach se ejecutan repetidamente mientras se cumple una condicin. Tambin se conocen como instrucciones de bucle. Cada una de estas instrucciones est pensada para un estilo de iteracin distinto. Instrucciones de salto Las instrucciones goto, break y continue se usan para transferir el control incondicionalmente a otra instruccin.
Instrucciones y excepciones
Explicacin previa
Las instrucciones if y switch se conocen como instrucciones condicionales, ya que toman decisiones en funcin del valor de expresiones y ejecutan unos comandos u otros en funcin de las decisiones tomadas. Al final de esta leccin, usted ser capaz de: Usar la instruccin if en C#. Usar la instruccin switch en C#.
Instrucciones y excepciones
La instruccin if
Objetivo del tema
Describir la instruccin if.
Explicacin previa
Sintaxis:
if ( expresin-booleana ) if ( expresin-booleana ) primera-instruccin-incrustada primera-instruccin-incrustada else else segunda-instruccin-incrustada segunda-instruccin-incrustada
A menudo los programas tienen que ejecutar distintas instrucciones dependiendo de una condicin.
Recomendacin al profesor
La instruccin if es la ms utilizada para tomar decisiones. Puede estar asociada con una clusula opcional else, como se muestra aqu:
if ( expresin-booleana ) primera-instruccin-incrustada else segunda-instruccin-incrustada
La sintaxis de la instruccin if no es ninguna novedad para los programadores de C y C++, as que procure no dedicar demasiado tiempo a este tema y concntrese en las diferencias entre C# y otros lenguajes, y en particular en la ausencia de una conversin predeterminada de un valor entero en otro booleano. Muestre un ejemplo de una instruccin if que tenga un bloque incrustado, y utilice este ejemplo para explicar cmo declarar una variable dentro de un bloque.
La instruccin if evala una expresin booleana para determinar el curso de accin a tomar. Si el resultado de la expresin booleana es true, el control pasa a la primera instruccin; si es false y existe una clusula else, el control se transfiere a la segunda instruccin.
Instrucciones y excepciones
Ejemplos
Se puede utilizar una instruccin if sencilla, como la siguiente:
if (numero % 2 == 0) Console.WriteLine("par");
Aunque las instrucciones incrustadas no necesitan llaves, muchas guas de estilo recomiendan utilizarlas porque previenen errores y hacen que el cdigo sea ms fcil de mantener. El ejemplo anterior se puede reescribir con llaves, como vemos:
if (numero % 2 == 0) { Console.WriteLine("par"); }
Instrucciones y excepciones
Instrucciones if en cascada
Objetivo del tema
Explicar cmo usar instrucciones condicionales complejas.
Explicacin previa
enum Palo { Treboles, Corazones, Diamantes, Picas} enum Palo { Treboles, Corazones, Diamantes, Picas} Palo cartas = Palo.Corazones; Palo cartas = Palo.Corazones; if (cartas == Palo.Treboles) if (cartas == Palo.Treboles) color = Negro; color = Negro; else if (cartas == Palo.Corazones) else if (cartas == Palo.Corazones) color = Rojo"; color = Rojo"; else if (palo == Palo.Diamantes) else if (palo == Palo.Diamantes) color = "Rojo"; color = "Rojo"; else else color = Negro"; color = Negro";
Recomendacin al profesor
El cdigo de ejemplo mostrado en la transparencia aparecer modificado cuando se estudie la instruccin switch. Puede ser conveniente repasar esta transparencia despus de ver la instruccin switch.
Para las instrucciones if en cascada se utiliza else if. C# no incluye la instruccin else if, sino que forma una instruccin del mismo tipo a partir de una clusula else y una instruccin if, como en C y C++. En otros lenguajes, como Visual Basic, se crean cascadas de instrucciones if colocando una instruccin else if entre la instruccin if y la instruccin final else. La instancia else if permite tener un nmero arbitrario de ramas. No obstante, las instrucciones controladas por una instruccin if en cascada son mutuamente excluyentes, lo que significa que slo se ejecuta una instruccin de entre todas las instancias else if.
Instrucciones y excepciones
10
Instrucciones if anidadas
El anidamiento de una instruccin if dentro de otra puede crear una ambigedad llamada dangling else (else pendiente), como se ve en el siguiente ejemplo:
if (porciento >= 0 && porciento <= 100) if (porciento > 50) Console.WriteLine("Pasa"); else Console.WriteLine("Error: fuera del intervalo");
La clusula else aparece indentada en la misma columna que el primer if, por lo que al leer el cdigo no parece que el else est asociado al segundo if. Esto puede resultar peligroso, ya que el compilador vincula una clusula else a su instruccin if ms cercana independientemente del diseo del programa. Esto significa que el compilador interpretar el cdigo anterior de la siguiente manera:
if (porciento >= 0 && porciento <= 100) { if (porciento > 50) Console.WriteLine("Pasa"); else Console.WriteLine("Error: fuera del intervalo"); }
Consejo Es recomendable escribir instrucciones if en cascada con la indentacin adecuada, ya que de lo contrario las decisiones largas se hacen rpidamente ilegibles y superan el margen derecho de la pgina o pantalla.
Instrucciones y excepciones
11
La instruccin switch
Objetivo del tema
Explicar una forma alternativa de tomar decisiones complejas.
Explicacin previa
Las instrucciones if anidadas pueden resultar confusas a la hora de expresar condiciones complejas. En algunos casos, pero no en todos, es posible utilizar la instruccin switch como alternativa.
Recomendacin al profesor
Se dice a menudo que en programas orientados a objetos se debe evitar la instruccin switch. Por supuesto, esto se debe a que muchas instrucciones switch utilizan un marcador de tipo en lugar de un polimorfismo. La instruccin switch se puede emplear para tomar decisiones en funcin del valor de un dato, y es especialmente adecuada para determinar el valor de una variable enum.
La instruccin switch proporciona un mecanismo elegante para expresar condiciones complejas que, de lo contrario, requeriran el uso de instrucciones if anidadas. Consta de bloques de varios casos, cada uno de los cuales especifica una sola constante y una etiqueta case asociada. No est permitido agrupar varias constantes en una sola etiqueta case, sino que cada constante debe tener la suya propia. Un bloque switch puede contener declaraciones. El mbito de una constante o variable local declarada en un bloque switch se extiende desde su declaracin hasta el final del bloque switch, como se ve en el ejemplo de la transparencia.
Instrucciones y excepciones
12
Una instruccin switch slo se puede utilizar para evaluar los siguientes tipos de expresiones: cualquier tipo entero, un char, una enum o una string. Tambin es posible evaluar otros tipos de expresiones con la instruccin switch, siempre y cuando haya exactamente una conversin implcita definida por el usuario del tipo no permitido a uno de los tipos permitidos. Nota Al contrario de lo que ocurre en Java, C o C++, el tipo que rige una instruccin switch en C# puede ser una cadena. Con una expresin de cadena, la constante de una etiqueta case puede tener el valor null. Para ms informacin sobre operadores de conversin, busque operadores de conversin en los documentos de ayuda del SDK de Microsoft .NET Framework.
Grupos de constantes
Para agrupar varias constantes hay que repetir la palabra clave case para cada una de ellas, como se muestra en el siguiente ejemplo:
enum MesNombre { Enero, Febrero, ..., Diciembre } MesNombre actual; int mesDias; ... switch (actual) { case MesNombre.Febrero : mesDias = 28; break; case MesNombre.Abril : case MesNombre.Junio : case MesNombre.Septiembre : case MesNombre.Noviembre : mesDias = 30; break; default : mesDias = 31; break; }
Las etiquetas case y default se utilizan nicamente como puntos de entrada para el flujo de control del programa en funcin del valor de la expresin switch, pero no modifican el flujo de control. Los valores de las constantes en las etiquetas case deben ser nicos, lo que significa que no puede haber dos constantes con el mismo valor. Por ejemplo, este ejemplo generar un error en tiempo de compilacin:
switch (cartas) { case Palo.Treboles : case Palo.Treboles: // Error: etiqueta duplicada ... default : default : // Error: etiqueta duplicada de nuevo ... }
Instrucciones y excepciones
13
Instrucciones y excepciones
14
= "th";
La regla de cada en cascada permite reordenar las secciones de una instruccin switch sin afectar a su comportamiento general.
Instrucciones y excepciones
15
Explicacin previa
La instruccin while La instruccin do La instruccin for La instruccin foreach Problema: Dnde est el error?
Las instrucciones while, do, for y foreach se conocen como instrucciones iterativas. Se puede utilizar para realizar operaciones mientras se cumple una condicin. Al final de esta leccin, usted ser capaz de: Usar instrucciones iterativas en C#. Identificar errores en el uso de instrucciones iterativas en C#.
Instrucciones y excepciones
16
La instruccin while
Describir la instruccin while.
Explicacin previa
Ejecuta instrucciones en funcin de un valor booleano Evala la expresin booleana al principio del bucle Ejecuta las instrucciones mientras el valor booleano sea True
int i = 0; int i = 0; while (i < 10) { while (i < 10) { Console.WriteLine(i); Console.WriteLine(i); i++; i++; } }
A menudo hay que ejecutar varias veces el mismo bloque de instrucciones hasta que se cumple una condicin.
0 1 2 3 4 5 6 7 8 9
Recomendacin al profesor
Insista en que tampoco en este caso hay conversin implcita de un entero en un valor booleano. La expresin booleana de control debe ser genuinamente booleana.
La instruccin while es la ms sencilla de todas las instrucciones iterativas. Ejecuta repetidamente una instruccin mientras (while) se cumpla una expresin booleana. La expresin evaluada por la instruccin while tiene que ser booleana, ya que C# no permite la conversin implcita de un entero en un valor booleano.
Flujo de ejecucin
Una instruccin while se ejecuta de la siguiente manera: 1. Se evala la expresin booleana que controla la instruccin while. 2. Si la expresin booleana se cumple (true), el control pasa a la instruccin incrustada. Al llegar al final de la misma, el control se transfiere implcitamente al inicio de la instruccin while y se vuelve a evaluar la expresin booleana. 3. Si la expresin booleana no se cumple (false), el control pasa al final de la instruccin while. Por lo tanto, el programa ejecuta repetidamente la instruccin incrustada mientras la expresin booleana de control sea true. La expresin booleana se prueba al inicio del bucle while, por lo que es posible que la instruccin incrustada no se llegue a ejecutar.
Instrucciones y excepciones
17
Ejemplos
Se puede utilizar una instruccin incrustada sencilla como en este ejemplo:
while (i < 10) Console.WriteLine(i++);
No es necesario utilizar llaves para las instrucciones incrustadas, aunque muchas guas de estilo recomiendan hacerlo ya que facilitan el mantenimiento. El ejemplo anterior se puede reescribir con llaves, como vemos:
while (i < 10) { Console.WriteLine(i++); }
Consejo A pesar de ser la instruccin iterativa ms simple, while puede crear problemas a los desarrolladores si no tienen el cuidado necesario. La sintaxis habitual de una instruccin while es la siguiente:
inicializacin while ( expresin-booleana ) { instruccin-incrustada actualizacin }
Es muy fcil olvidarse de la parte de actualizacin en el bloque while, especialmente si se est pensando slo en la expresin booleana.
Instrucciones y excepciones
18
La instruccin do
Objetivo del tema
Explicar el uso de la instruccin do.
Explicacin previa
Ejecuta instrucciones en funcin de un valor booleano Evala la expresin booleana al final del bucle Ejecuta las instrucciones mientras el valor booleano sea True
int i = 0; int i = 0; do { do { Console.WriteLine(i); Console.WriteLine(i); i++; i++; } while (i < 10); } while (i < 10);
En ocasiones puede ser necesario comprobar la condicin que controla un bucle al final de una iteracin, en lugar de al principio.
0 1 2 3 4 5 6 7 8 9
Una instruccin do va siempre acompaada de una instruccin while y es similar a sta, salvo en que la expresin booleana que determina si hay que salir del bucle o continuar se evala al final del bucle en lugar de al principio. Esto quiere decir que, al contrario de la instruccin while, que efecta cero o ms iteraciones, una instruccin do realiza una o ms iteraciones. Por lo tanto, la instruccin incrustada de una instruccin do se ejecuta siempre al menos una vez. Esto resulta especialmente til cuando es necesario validar la entrada antes de permitir que contine la ejecucin del programa.
Flujo de ejecucin
Una instruccin do se ejecuta de la siguiente manera: 1. El control pasa a la instruccin incrustada. 2. Al llegar al final de la instruccin incrustada, se evala la expresin booleana. 3. Si la expresin booleana se cumple (true), el control pasa al inicio de la instruccin do. 4. Si la expresin booleana no se cumple (false), el control pasa al final de la instruccin do.
Instrucciones y excepciones
19
Ejemplos
Se puede utilizar una instruccin incrustada sencilla como en este ejemplo:
do Console.WriteLine(i++); while (i < 10);
Como ocurre con las instrucciones if y while, no es necesario, aunque s conveniente, utilizar llaves para las instrucciones incrustadas. Tambin es posible usar un bloque de instrucciones do como en este ejemplo:
do { Console.WriteLine(i); i++; } while (i < 10);
Como se ve, una instruccin do tiene que terminar siempre con punto y coma:
do { Console.WriteLine(i++); } while (i < 10) // Error: no hay ;
Instrucciones y excepciones
20
La instruccin for
Objetivo del tema
Explicar el uso de la instruccin for.
Explicacin previa
La mayor parte de los bucles iterativos siguen un mismo patrn: Inicializan una variable de control, prueban una condicin, ejecutan un bloque de instrucciones y actualizan al variable de control.
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++) Console.WriteLine(i); Console.WriteLine(i); Un bucle for puede // Error: i est fuera de mbito Console.WriteLine(i);iterar Error: i est fuera de mbito Console.WriteLine(i); // varios valores
for (int i = 0, j = 0; ... ; i++, j++) for (int i = 0, j = 0; ... ; i++, j++)
Recomendacin al profesor
La condicin es en realidad una expresin booleana. Se emplea la palabra condicin porque es la que se utiliza en la documentacin e referencia del lenguaje C#. Destaque el cambio en la posicin del cdigo de actualizacin y el distinto mbito de la variable de iteracin en la instruccin for.
Los desarrolladores cometen a menudo el error de olvidarse de actualizar la variable de control cuando utilizan instrucciones while, como muestra el siguiente ejemplo:
int i = 0; while (i < 10) Console.WriteLine(i); // Error: falta i++
Este error se debe a que los programadores centran su atencin en el cuerpo de la instruccin while y no en la actualizacin. Adems, el cdigo de actualizacin puede estar muy alejado de la palabra clave while. La instruccin for evita el problema y reduce este tipo de errores al mnimo, ya que pasa el cdigo de actualizacin al principio del bucle, donde es ms difcil de olvidar. La sintaxis de la instruccin for es la siguiente:
for ( inicializacin ; condicin ; actualizacin ) instruccin-incrustada
Importante El cdigo de actualizacin en una instruccin for est antes que la instruccin incrustada, pero se ejecuta despus.
Instrucciones y excepciones
21
La sintaxis de la instruccin for es prcticamente idntica a la de la instruccin while, como muestra el siguiente ejemplo:
inicializacin while (condicin) { instruccin-incrustada actualizacin }
Como en las dems instrucciones iterativas, la condicin en un bloque for debe ser una expresin booleana que funciona como condicin para la continuacin, no para la terminacin.
Ejemplos
Los componentes de inicializacin, condicin y actualizacin de una instruccin for son opcionales. No obstante, una condicin vaca se considera un true implcito y puede producir fcilmente un bucle infinito, como se ve en el siguiente ejemplo:
for (;;) { Console.WriteLine("Ayuda "); ... }
Como con las instrucciones while y do, se puede utilizar una instruccin incrustada sencilla o un bloque de instrucciones, como en estos ejemplos:
for (int i = 0; i < 10; i++) Console.WriteLine(i); for (int i = 0; i < 10; i++) { Console.WriteLine(i); Console.WriteLine(10 i); }
Instrucciones y excepciones
22
Declaracin de variables
Una sutil diferencia entre las instrucciones while y for es que una variable declarada en el cdigo de inicializacin de una instruccin for slo tiene validez dentro de ese bloque for. Por ejemplo, el siguiente cdigo generar un error en tiempo de compilacin:
for (int i = 0; i < 10; i++) Console.WriteLine(i); Console.WriteLine(i); // Error: i est fuera de mbito
Adems de esto, hay que tener en cuenta que una variable en un bloque for no se puede declarar con el mismo nombre que una variable en un bloque externo. Esta regla tambin es vlida para variables declaradas en el cdigo de inicializacin de una instruccin for. Por ejemplo, el siguiente cdigo generar un error en tiempo de compilacin:
int i; for (int i = 0; i < 10; i++) // Error: i ya est en mbito
Por otra parte, es posible inicializar dos o ms variables en el cdigo de inicializacin de una instruccin for:
for (int i = 0, j = 0; ... ; ...)
Sin embargo, las variables tienen que ser del mismo tipo. Por lo tanto, el siguiente cdigo no est permitido:
for (int i = 0, long j = 0; i < 10; i++) ...
Tambin se pueden usar dos o ms expresiones separadas por una o ms comas en el cdigo de inicializacin de una instruccin for:
for (int i = 0, j = 0; ... ; i++, j++)
La instruccin for resulta muy til cuando no se conoce el nmero de iteraciones, y especialmente para modificar todos los elementos de una tabla.
Instrucciones y excepciones
23
La instruccin foreach
Objetivo del tema
Describir la instruccin foreach.
Elige el tipo y el nombre de la variable de iteracin Ejecuta instrucciones incrustadas para cada elemento de la clase collection
ArrayList numeros = new ArrayList( ); ArrayList numeros = new ArrayList( ); for (int i = 0; i < 10; i++ ) { for (int i = 0; i < 10; i++ ) { numeros.Add(i); numeros.Add(i); } } foreach (int number in numeros) { foreach (int number in numeros) { Console.WriteLine(numero); Console.WriteLine(numero); } }
Explicacin previa
Es habitual hacer iteraciones para todos los elementos de una lista o coleccin.
0 1 2 3 4 5 6 7 8 9
Recomendacin al profesor
Este tema es difcil de explicar. Recuerde que todava no se han discutido ni las matrices ni las clases de coleccin. La mejor forma de explicar este tema es concentrarse en la cantidad de sintaxis que se puede eliminar en una instruccin foreach en comparacin con una instruccin for.
Las colecciones son entidades software cuyo propsito es reunir otras entidades software, del mismo modo que un libro de cuentas se puede considerar una coleccin de cuentas bancarias o que una casa puede ser una coleccin de habitaciones. Microsoft .NET Framework contiene una clase de coleccin sencilla llamada ArrayList, que se puede emplear para crear una variable de coleccin y aadir elementos a la coleccin. Por ejemplo, consideremos el siguiente cdigo:
using System.Collections; ... ArrayList numeros = new ArrayList( ); for (int i = 0; i < 10; i++) { numeros.Anadir(i); }
Es posible escribir una instruccin for para acceder por turno a cada elemento de la coleccin en esta clase de coleccin e imprimirlo:
for (int i = 0; i < numero.Cuenta; i++) { int numero = (int)numeros[i]; Console.WriteLine(numero); }
Esta instruccin for contiene muchas instrucciones individuales que, combinadas, ponen en marcha el mecanismo empleado para iterar cada elemento de la coleccin de nmeros. No obstante, esta solucin no resulta sencilla y es propicia al error.
Instrucciones y excepciones
24
Para resolver este problema en C# se puede utilizar la instruccin foreach, que permite iterar toda una coleccin sin necesidad de instrucciones mltiples. En lugar de extraer explcitamente cada elemento de una coleccin usando sintaxis especfica para cada coleccin, la instruccin foreach hace todo lo contrario e indica a la coleccin que vaya presentando sus elementos de uno en uno; en vez de llevar la instruccin incrustada a la coleccin, lleva la coleccin a la instruccin incrustada. Con la instruccin foreach se puede reescribir la instruccin for anterior de la siguiente manera:
foreach (int numero in numeros) Console.WriteLine(numero);
La instruccin foreach ejecuta la instruccin incrustada para cada elemento de la clase de coleccin numeros. Slo hay que elegir el tipo y el nombre de la variable de iteracin, que en este caso son int y numero, respectivamente. No es posible modificar los elementos de una coleccin utilizando una instruccin foreach porque implcitamente la variable de iteracin es readonly (slo lectura). Por ejemplo:
foreach (int numero in numeros) { numero++; // Error en tiempo de compilacin Console.WriteLine(numero); }
Consejo Se puede emplear una instruccin foreach para iterar los valores de un enumerador utilizando el mtodo Enum.GetValues(), que devuelve una tabla de objetos. Hay que tomar precauciones cuando se decide el tipo de la variable de iteracin foreach. En algunos casos es posible que en tiempo de ejecucin no se detecte un tipo errneo de variable de iteracin.
Instrucciones y excepciones
25
Explicacin previa
Las instrucciones goto, break y continue se conocen como instrucciones de salto y se utilizan para pasar el control de un punto del programa a otro en cualquier momento. En esta seccin veremos cmo usar instrucciones de salto en programas C#.
Instrucciones y excepciones
26
La instruccin goto
Objetivo del tema
Explicar cmo transferir el control de forma incondicional a otra parte de un mtodo.
Explicacin previa
Transfiere el flujo de control a una instruccin con etiqueta Pueden dar lugar fcilmente a cdigo spaghetti de difcil interpretacin
if (numero % 2 == 0) goto Par; if (numero % 2 == 0) goto Par; Console.WriteLine(impar"); Console.WriteLine(impar"); goto Fin; goto Fin; Par: Par: Console.WriteLine(par"); Console.WriteLine(par"); Fin:; Fin:;
La instruccin goto permite pasar el control a otra instruccin dentro del mismo programa.
Recomendacin al profesor
La principal razn para dedicar un tema propio a goto es que la instruccin switch interacta con ella de formas que no son posibles en Java, C++ o C. La instruccin goto puede estar vinculada al "hiperespacio".
La instruccin goto es la ms primitiva de las instrucciones de salto en C#. Transfiere el control a una instruccin con etiqueta. Esta etiqueta debe existir y estar en el mbito de la instruccin goto. Es posible que varias instrucciones goto pasen el control a una misma etiqueta. La instruccin goto puede transferir el control fuera de un bloque, pero nunca dentro de l. El objetivo de esta restriccin, que existe tambin en C++ y otros lenguajes, es evitar la posibilidad de que se salte una inicializacin. Dentro del cdigo puede haber mucha distancia entre la instruccin goto y la instruccin de destino con etiqueta. Esta distancia puede dificultar la interpretacin de la lgica del flujo de control, por lo que la mayor parte de las guas de programacin recomiendan no utilizar instrucciones goto. Nota El uso de instrucciones goto est recomendado nicamente en instrucciones switch o para pasar el control fuera de un bucle anidado.
Instrucciones y excepciones
27
Explicacin previa
La instruccin break salta fuera de una iteracin La instruccin continue salta a la siguiente iteracin
int i = 0; int i = 0; while (true) { while (true) { Console.WriteLine(i); Console.WriteLine(i); i++; i++; if (i < 10) if (i < 10) continue; continue; else else break; break; } }
Recomendacin al profesor
Aunque no resulte obvio (y eso es lo importante) el cdigo mostrado en la transparencia escribe los valores del cero al nueve.
Una instruccin break abandona la instruccin switch, while, do, for o foreach ms prxima. Una instruccin continue comienza una nueva iteracin de la instruccin while, do, for o foreach ms prxima. Las instrucciones break y continue no se diferencian demasiado de una instruccin goto, cuyo uso puede dificultar la interpretacin de la lgica del flujo de control. Por ejemplo, la instruccin while se puede reescribir de la siguiente manera sin emplear break ni continue:
int i = 0; while (i < 10) { Console.WriteLine(i); i++; }
Lo mejor es reescribir el cdigo anterior con una instruccin for, como sigue:
for (int i = 0; i < 10; i++) { Console.WriteLine(i); }
Instrucciones y excepciones
28
Explicacin previa
Por qu se emplean excepciones? Objetos excepcin Uso de bloques try-catch Bloques catch mltiples
La capacidad de capturar y tratar excepciones es una parte importante de cualquier programa C#.
Antes o despus, todos los desarrolladores tienen que dedicar ms tiempo a la bsqueda y tratamiento de errores que a escribir la lgica del programa. Para paliar este problema se utilizan las excepciones, que estn pensadas para tratar errores. En esta seccin aprender a capturar y tratar excepciones en C#.
Instrucciones y excepciones
29
Explicacin previa
Hay que estar siempre preparado para cualquier imprevisto que pueda surgir durante la ejecucin de un programa.
int errorCodigo = 0; int errorCodigo = 0; FileInfo source = new FileInfo("code.cs"); FileInfo source = new FileInfo("code.cs"); if (errorCodigo == -1) goto Fallo; if (errorCodigo == -1) goto Fallo; int longitud = (int)source.Length; int longitud = (int)source.Length; if (errorCodigo == -2) goto Fallo; if (errorCodigo == -2) goto Fallo; char[] contenido = new char[longitud]; char[] contenido = new char[longitud]; if (errorCodigo == -3) goto Fallo; if (errorCodigo == -3) goto Fallo; // No hay problemas ... // No hay problemas ... Fallo: ... Fallo: ... Trat. De errores Trat. De errores
Un buen programa se caracteriza por incluir medidas contra lo inesperado y por poderse recuperar en caso de que ocurra. Pueden aparecer errores en cualquier momento durante la compilacin o ejecucin de un programa. La lgica bsica del programa mostrado en la transparencia es la siguiente: Recomendacin al profesor
ArchInfo source = new ArchInfo("code.cs"); int longitud = (int)source.Longitud; char[ ] contenido = new char[longitud]; ...
Estas tres instrucciones volvern a aparecer en muchos de los temas siguientes. Pida a los estudiantes que le digan los problemas asociados con el cdigo y vea cuntos se les ocurren.
Desgraciadamente, estas instrucciones bsicas se pierden en la confusin del cdigo para tratamiento de errores. Este cdigo dificulta la interpretacin de la lgica del programa de distintas maneras: La lgica del programa se mezcla con el cdigo para tratamiento de errores. Las instrucciones bsicas del programa pierden su integridad conceptual al mezclarse con el cdigo para tratamiento de errores, lo que hace que sea difcil entender el programa. Todo el cdigo para errores tiene un aspecto similar. Todas las instrucciones para tratamiento de errores son similares, ya que todas utilizan instrucciones if para probar el mismo cdigo de error. Adems hay mucho cdigo repetido, lo que siempre es una seal de aviso. Los cdigos de error no son significativos en s mismos. En este cdigo, un nmero como 1 no tiene un significado explcito; podra representar Error de seguridad: no hay permiso de lectura, pero eso slo se puede saber consultando la documentacin. Por lo
Instrucciones y excepciones
30
tanto, los cdigos enteros de error son muy programticos y no describen los errores que representan.
Instrucciones y excepciones
31
Los cdigos de error se definen a nivel de mtodo. Cada mtodo comunica su error asignando al cdigo de error un valor concreto y exclusivo. No hay dos mtodos que usen el mismo valor. Esto significa que cada mtodo est vinculado a todos los dems, lo que se puede ver claramente si se cambian los cdigos enteros de error por una enumeracin, como en el siguiente cdigo:
Este cdigo es mejor: Un identificador como ArchivoNoEncontrado es siempre ms descriptivo que 1. Sin embargo, cada vez que se aada un nuevo error con nombre a la enum, se vern afectados todos los mtodos que nombren sus errores en la enum y ser necesario volver a compilar. Los enteros simples tienen una capacidad de descripcin limitada. Por ejemplo, la documentacin puede indicar que 1 significa Error de seguridad: no hay permiso de lectura, pero 1 podra ser tambin el nombre del archivo que no se puede leer. Es fcil pasar por alto cdigos de error. Por ejemplo, los programadores en C casi nunca comprueban el int que devuelve la funcin printf. Es poco probable que printf falle, pero en caso de hacerlo devolver un valor entero negativo (normalmente 1). Como vemos, es necesaria una alternativa al mtodo tradicional de tratamiento de errores. Las excepciones ofrecen una alternativa que es ms flexible, requiere menos espacio y produce mensajes de error significativos.
Instrucciones y excepciones
32
Objetos excepcin
Objetivo del tema
Explicar el uso de objetos de excepciones.
Explicacin previa
Cuando se produce una excepcin es necesario saber a qu se debe y qu informacin est asociada al error.
Exception Exception SystemException SystemException OutOfMemoryException OutOfMemoryException IOException IOException NullReferenceException NullReferenceException ApplicationException ApplicationException
Recomendacin al profesor
Los cdigos de error de programacin empleados en el cdigo procedural para tratamiento de errores son similares al siguiente:
enum CodigoError { ErrorSeguridad = -1, ErrorIO = -2, ErrorMemoriaInsuficiente = -3, ... }
El objetivo de este tema es ofrecer una introduccin a los objetos Exception. No est pensado para que se explique con detalle cmo crear nuevos objetos excepcin.
El uso de estos cdigos de error hace difcil proporcionar informacin que sea til para recuperarse del error. Por ejemplo, en caso de un ErrorIO no se recibe informacin sobre de qu tipo de error se trata. Ser un intento de escritura en un archivo de slo lectura o un archivo inexistente, o se deber a un disco daado? Y cul es el archivo que se intenta leer o escribir? Para solucionar este problema de falta de informacin sobre el error generado, en .NET Framework se ha definido una serie de clases de excepcin.
Instrucciones y excepciones
33
Todas las excepciones se derivan de la clase llamada Exception, que es parte del runtime de lenguaje comn. La transparencia muestra la jerarqua de estas excepciones. Las clases de excepcin ofrecen las siguientes ventajas: Los mensajes de error no estn representados por valores enteros o enumeraciones. Los valores enteros de programacin, como -3, desparecen y en su lugar se utilizan clases de excepcin concretas, como OutOfMemoryException. Cada clase de excepcin puede residir dentro de su propio archivo de origen y no est vinculada con las dems clases de excepcin. Se generan mensajes de error significativos. Cada clase de excepcin es descriptiva y representa un error concreto de forma clara y evidente. En lugar de un 3, se utiliza una clase llamada OutOfMemoryException. Cada clase de excepcin contiene tambin informacin especfica. Por ejemplo, una clase FileNotFoundException podra contener el nombre del archivo no encontrado. Consejo Para emplear excepciones de forma eficaz es necesario mantener un equilibrio entre clases de excepcin demasiado vagas y otras que son demasiado precisas. Si la clase de excepcin es demasiado vaga, no ser posible escribir un bloque catch til. Por otra parte, no es conveniente crear una clase de excepcin demasiado precisa, ya que puede filtrar datos de funcionamiento y rompe la encapsulacin.
Instrucciones y excepciones
34
Explicacin previa
Solucin orientada a objetos para el tratamiento de errores Poner el cdigo normal en un bloque try Tratar las excepciones en un bloque catch aparte
try { try { Console.WriteLine("Escriba un nmero"); Console.WriteLine("Escriba un nmero"); del programa Lgica int i = int.Parse(Console.ReadLine()); Lgica del programa int i = int.Parse(Console.ReadLine());
Tratamiento de errores Tratamiento de errores
Recomendacin al profesor
El objetivo de esta transparencia es explicar cmo try y catch permiten resolver muchos de los problemas asociados con el mtodo procedural de tratamiento de errores. Por supuesto, el tema no se trata en profundidad. El punto principal que no se trata es la forma en que la instruccin throw desenreda la pila de llamadas. Esto se explicar en una transparencia posterior, as que no hay que entrar en detalles ahora. En la transparencia se usa un solo bloque catch general que capturar todas las excepciones. No dedique mucho tiempo a este tema, ya que an no se ha explicado la herencia.
Los bloques try-catch son la solucin que ofrece la orientacin a objetos a los problemas de tratamiento de errores. La idea consiste en separar fsicamente las instrucciones bsicas del programa para el flujo de control normal de las instrucciones para tratamiento de errores. As, las partes del cdigo que podran lanzar excepciones se colocan en un bloque try, mientras que el cdigo para tratamiento de excepciones en el bloque try se pone en un bloque catch aparte. La sintaxis de un bloque catch es la siguiente:
catch ( tipo-de-clase identificador ) { ... }
El tipo de clase tiene que ser System.Exception o un tipo derivado de System.Exception. El identificador, que es opcional, es una variable local de slo lectura en el mbito del bloque catch.
catch (Exception capturada) { ... } Console.WriteLine(capturada); // Error en tiempo de compilacin: // capturada est fuera de mbito
Instrucciones y excepciones
35
El ejemplo de la transparencia ilustra el uso de las instrucciones try y catch. El bloque try contiene una expresin que puede generar la excepcin. En caso de producirse la excepcin, el runtime detiene la ejecucin normal y empieza a buscar un bloque catch que pueda capturar la excepcin pendiente (basndose en su tipo). Si en la funcin inmediata no se encuentra un bloque catch adecuado, el runtime desenreda la pila de llamadas en busca de la funcin de llamada. Si tampoco ah encuentra un bloque catch apropiado, busca la funcin que llam a la funcin de llamada y as sucesivamente hasta encontrar un bloque catch (o hasta llegar al final de Main, en cuyo caso se cerrar el programa). Si encuentra un bloque catch, se considera que la excepcin ha sido capturada y se reanuda la ejecucin normal desde el cuerpo del bloque catch (que, en el caso de la transparencia, escribe el mensaje contenido en el objeto excepcin OverflowException). Por lo tanto, el uso de bloques try-catch hace que las instrucciones para tratamiento de errores no se mezclen con las instrucciones lgicas bsicas, por lo que el programa es ms fcil de interpretar.
Instrucciones y excepciones
36
Cada bloque catch captura una clase de excepcion Un bloque try puede tener un bloque catch general Un bloque try no puede capturar una clase derivada de una clase capturada en un bloque catch anterior
try try { { Console.WriteLine(Escriba el primer nmero"); Console.WriteLine(Escriba el primer nmero"); int i = int.Parse(Console.ReadLine()); int i = int.Parse(Console.ReadLine()); Console.WriteLine("Escriba el segundo nmero"); Console.WriteLine("Escriba el segundo nmero"); int j = int.Parse(Console.ReadLine()); int j = int.Parse(Console.ReadLine()); int k = i / j; int k = i / j;
Explicacin previa
} } catch (OverflowException capturada) {} catch (OverflowException capturada) {} catch (DivideByZeroException capturada) {} catch (DivideByZeroException capturada) {}
Un bloque de cdigo en una instancia try puede contener muchas instrucciones, cada una de las cuales puede producir una o ms clases diferentes de excepcin. Al haber muchas clases de excepciones distintas, es posible que haya muchos bloques catch y que cada uno de ellos capture un tipo especfico de excepcin. La captura de una excepcin se basa nicamente en su tipo. El runtime captura automticamente objetos excepcin de un tipo concreto en un bloque catch para ese tipo. El siguiente cdigo ayudar a comprender mejor lo que ocurre en un bloque try-catch mltiple:
1. try { 2. Console.WriteLine("Escriba el primer nmero"); 3. int i = int.Parse(Console.ReadLine()); 4. Console.WriteLine("Escriba el segundo nmero"); 5. int j = int.Parse(Console.ReadLine()); 6. int k = i / j; 7. } 8. catch (OverflowException capturada) 9. { 10. Console.WriteLine(capturada); 11. } 12. catch(DivideByZeroException capturada) 13. { 14. Console.WriteLine(capturada); 15. } 16. ...
Instrucciones y excepciones
37
La lnea 3 inicializa int i con un valor ledo de la consola. Esto puede lanzar un objeto excepcin de clase OverflowException, en cuyo caso no se ejecutarn las lneas 4, 5 y 6. Se suspende la secuencia de ejecucin normal y el control pasa al primer bloque catch que pueda capturar esa excepcin, que en este ejemplo est en la lnea 8. Una vez transferido el control, se ejecuta la instruccin hasta la llave de cierre y se devuelve el control a la lnea 16. Por otra parte, es posible que las lneas 3 a 5 no lancen ninguna excepcin. En ese caso, la ejecucin continuar normalmente hasta la lnea 6, que puede lanzar un objeto excepcin de clase DivideByZeroException. Si eso ocurre, el flujo de control salta al bloque catch de la lnea 12, que se ejecuta normalmente y devuelve el control a la lnea 16. Si ninguna de las instrucciones en el bloque try lanza una excepcin, el flujo de control llega al final del bloque try y pasa a la lnea 16. Hay que tener en cuenta que el flujo de control slo entra en un bloque catch si se lanza una excepcin. Las instrucciones de un bloque try se pueden escribir sin preocuparse del posible fallo de una instruccin anterior en el bloque try. En caso de que una instruccin anterior produzca una excepcin, el flujo de control no llegar a alcanzar las instrucciones siguientes en el bloque try. Si el flujo de control no encuentra ningn bloque catch adecuado, detendr la llamada al mtodo en que se encuentre y continuar buscando en la instruccin desde la que se hizo la llamada al mtodo. La bsqueda seguir desenredando la pila de llamadas hasta llegar a Main, si es necesario. Si esto causa la finalizacin de Main, el proceso o subproceso que hubiera llamado a Main terminar de una forma definida previamente.
Un bloque try no puede tener ms que un bloque catch general. Por ejemplo, el siguiente cdigo generar un error:
try { ... } catch { ... } catch { ... } // Error
Instrucciones y excepciones
38
En caso de existir, un bloque catch general debe ser el ltimo bloque catch en el programa:
try { ... } catch { ... } catch (OutOfMemoryException capturada) { ... } // Error
Se generar un error en tiempo de compilacin en caso de capturar dos veces la misma clase, como en el ejemplo siguiente:
catch (OutOfMemoryException capturada) { ... } catch (OutOfMemoryException capturada) { ... } // Error
Tambin se generar un error en tiempo de compilacin si se intenta capturar una clase derivada de otra capturada en un bloque catch anterior:
catch (Exception capturada) { ... } catch (OutOfMemoryException capturada) { ... } // Error
Este cdigo produce un error porque la clase OutOfMemoryException deriva de la clase SystemException, que a su vez deriva de la clase Exception.
Instrucciones y excepciones
39
Lanzamiento de excepciones
Objetivo del tema
Ofrecer una introduccin a los temas tratados en esta seccin.
Explicacin previa
La instruccin throw La clusula finally Comprobacin de desbordamiento aritmtico Normas para el tratamiento de excepciones
La capacidad de capturar y tratar excepciones es una parte importante de cualquier programa C#.
C# incluye la instruccin throw y la clusula finally, que permiten a los programadores lanzar excepciones cuando sea necesario y controlarlas convenientemente. Al final de esta leccin, usted ser capaz de: Lanzar sus propias excepciones. Activar la comprobacin de desbordamiento aritmtico.
Instrucciones y excepciones
40
La instruccin throw
Objetivo del tema
Explicar cmo lanzar excepciones.
Explicacin previa
Como parte del cdigo de comprobacin de errores, puede ser necesario lanzar excepciones propias.
Los bloques try y catch se pueden utilizar para capturar errores lanzados en un programa C#. Ya hemos visto cmo, en lugar de sealar un error devolviendo un valor especial o asignndolo a una variable de error global, C# hace que la ejecucin se transfiera a la clusula catch correspondiente.
Instrucciones y excepciones
41
En este ejemplo se emplea la instruccin throw para lanzar una excepcin definida por el usuario, InvalidTimeException, si el tiempo analizado no es vlido. En general, las excepciones esperan como parmetro una cadena con un mensaje significativo que se puede mostrar o quedar registrado cuando se captura la excepcin. Tambin es conveniente lanzar una clase adecuada de excepcin. Precaucin Los programadores en C++ ya estn acostumbrados a crear y lanzar un objeto excepcin con una sola instruccin, como muestra el siguiente cdigo:
throw out_of_range("ndice fuera de lmites");
Lanzamiento de objetos
Slo es posible lanzar un objeto si el tipo de ese objeto deriva directa o indirectamente de System.Exception. Esto es diferente a lo que ocurre en C++, donde se puede lanzar objetos de cualquier tipo, como en el siguiente cdigo:
throw 42; // Permitido en C++, pero no en C#
Se puede utilizar una instruccin throw en un bloque catch para volver a lanzar el mismo objeto excepcin, como en el siguiente ejemplo:
catch (Exception capturada) { ... throw capturada; }
Instrucciones y excepciones
42
En el ejemplo anterior, el objeto IOException y toda la informacin que contiene se pierde cuando la excepcin se convierte en un objeto FileNotFoundException. Es ms conveniente ajustar la excepcin, aadiendo nueva informacin pero conservando la que tiene, como se ve en el siguiente cdigo:
catch (IOException capturada) { ... throw new FileNotFoundException(nombre_de_archivo, capturada); }
La capacidad de asignar un objeto excepcin resulta especialmente til en las fronteras de un sistema con arquitectura multi-capa. Es posible usar una instruccin throw sin ninguna expresin, pero slo en un bloque catch. Vuelve a lanzar la excepcin que se est controlando en ese momento. En C++ esta accin tambin recibe el nombre de relanzamiento. Como consecuencia, estas dos lneas de cdigo darn el mismo resultado:
catch (OutOfMemoryException capturada) { throw capturada; } ... catch (OutOfMemoryException) { throw ; }
Instrucciones y excepciones
43
La clusula finally
Objetivo del tema
Explicar cmo limpiar recursos tras el lanzamiento de una excepcin.
Explicacin previa
Las excepciones siempre se producen en el momento ms inoportuno. La instruccin finally de C# permite liberar los recursos utilizados y evita la prdida de informacin.
Monitor.Enter(x); Monitor.Enter(x); try { try { ... ... } } finally { finally { Monitor.Exit(x); Monitor.Exit(x); } }
La clusula finally de C# contiene un conjunto de instrucciones que es necesario ejecutar sea cual sea el flujo de control. As, las instrucciones del bloque finally se ejecutarn aunque el control abandone un bucle try como resultado de la ejecucin normal porque el flujo de control llega al final del bloque try. Del mismo modo, tambin se ejecutarn las instrucciones del bloque finally si el control abandona un bucle try como resultado de una instruccin throw o una instruccin de salto como break, continue o goto. El bloque finally es til en dos casos: para evitar la repeticin de instrucciones y para liberar recursos tras el lanzamiento de una excepcin.
Repeticin de instrucciones
Si las instrucciones del final de un bloque try estn repetidas en un bloque catch general, se puede evitar la duplicacin pasando las instrucciones a un bloque finally. Consideremos el siguiente ejemplo:
try { ... instrucciones } catch { ... instrucciones }
Instrucciones y excepciones
44
Es un error que una instruccin break, continue o goto transfiera el control fuera de un bloque finally. Estas instrucciones slo se pueden utilizar si el objetivo del salto est en el mismo bloque finally. Sin embargo, siempre es un error que haya una instruccin return en un bloque finally, aunque sea la ltima instruccin del bloque. Si se lanza una excepcin durante la ejecucin de un bloque finally, se propagar hasta el siguiente bloque try ::
try { try { ... } catch { // EjemploExcepcion no se captura aqu } finally { throw new EjemploExcepcion ("quin me capturar?"); } } catch { // EjemploExcepcion se captura aqu }
Si se lanza una excepcin durante la ejecucin de un bloque finally y ya se estaba propagando otra excepcin, se perder la excepcin original:
try { throw new EjemploExcepcion ("Se pierde"); } finally { throw new EjemploExcepcion ("Se puede encontrar y capturar"); }
Instrucciones y excepciones
45
Explicacin previa
Por defecto, el desbordamiento aritmtico no se comprueba Un comando checked activa la comprobacin de desbordamiento
checked { checked { int numero = int.MaxValue; int numero = int.MaxValue; Console.WriteLine(++numero); Console.WriteLine(++numero); } } unchecked { unchecked { int numero = int.MaxValue; int numero = int.MaxValue; Console.WriteLine(++numero); Console.WriteLine(++numero); } }
OverflowException OverflowException
Se lanza un objeto excepcin. WriteLine no se ejecuta
La posibilidad de desbordamiento o subdesbordamiento aritmtico se puede capturar con algunas instrucciones adicionales.
MaxValue + 1 es negativo?
-2147483648
Por defecto, un programa C# no comprueba la posibilidad de desbordamiento aritmtico, como se puede ver en este ejemplo: Recomendacin al profesor
// ejemplo.cs class Ejemplo { static void Main( ) { int numero = int.ValorMax; Console.WriteLine(++numero); } }
Los diagramas de la transparencia representan deliberadamente el flujo de control normal con una flecha que apunta hacia abajo, y el flujo de control anormal con una flecha que apunta hacia arriba.
En este cdigo, numero se inicializa al valor mximo para un int. La expresin ++numero incrementa numero a 2147483648, el mayor valor int negativo, que se escribe en la consola. No se genera ningn mensaje de error.
Instrucciones y excepciones
46
El programa ejecutable resultante producir una excepcin de clase System.OverflowException. Del mismo modo, es posible desactivar globalmente la comprobacin del desbordamiento aritmtico utilizando la opcin de lnea de comandos /checked-:
c:\ csc /checked- ejemplo.cs
El programa ejecutable resultante ajustar el valor int a int.ValorMin y no producir una excepcin de clase System.OverflowException.
Independientemente del parmetro /checked de tiempo de compilacin, las instrucciones contenidas en una lista de instrucciones checked activan siempre la comprobacin del desbordamiento aritmtico. Del mismo modo, las instrucciones contenidas en una lista de instrucciones unchecked no activan nunca la comprobacin del desbordamiento aritmtico, independientemente del parmetro /checked de tiempo de compilacin.
Una expresin checked se revisa para ver si hay desbordamiento aritmtico, mientras que una expresin unchecked no se comprueba. Por ejemplo, el siguiente cdigo generar una System.OverflowException.
// ejemplo.cs class Ejemplo { static void Main( ) { int numero = int.ValorMax; Console.WriteLine(checked(++numero)); } }
Instrucciones y excepciones
47
Lanzamiento Evitar excepciones para casos normales o esperados Nunca crear ni lanzar objetos de clase Exception Incluir una cadena de descripcin en un objeto Exception Lanzar objetos de la clase ms especfica posible Captura Ordenar los bloques catch de lo especfico a lo general No permitir que salgan excepciones de Main
Explicacin previa
Hay una serie de prcticas recomendadas que es necesario seguir a la hora de escribir cdigo de calidad.
Siga las siguientes reglas para el tratamiento de excepciones: Evite excepciones para casos normales o esperados. Nunca cree ni lance objetos de clase Excepcin. Cree clases de excepcin derivadas directa o indirectamente de SystemException (y nunca desde la clase Excepcin raz). El siguiente cdigo muestra un ejemplo:
class SyntaxException : SystemException { ... }
Incluya una cadena de descripcin en un objeto Exception. Aada siempre una cadena de descripcin til en un objeto excepcin, como en este caso:
string descripcion = String.Format("{0}({1}): nueva lnea en constante de cadena", nombrearchivo, numerolinea); throw new SyntaxException(descripcion);
Lance objetos de la clase ms especfica posible. Lance la excepcin ms concreta posible cuando esa informacin pueda ser til al usuario. Por ejemplo, lance una FileNotFoundException mejor que una IOException ms general.
Instrucciones y excepciones
48
Ordene los bloques catch desde el ms especfico al ms general. Ordene los bloques catch desde la excepcin ms concreta a la excepcin ms general, como en este ejemplo:
catch (SyntaxException capturada) { ... } // Hacer esto catch (Exception capturada) { ... }
No deje que salgan excepciones de Main. Ponga una clusula catch general en Main para asegurarse de que nunca salen excepciones al final del programa.