C# Sentencias de Control
C# Sentencias de Control
C# Sentencias de Control
Otras versiones
Este capítulo describe las instrucciones de C# que se pueden utilizar en un programa. Salvo que se
indique otra cosa, las instrucciones se ejecutan secuencialmente. C# dispone de las siguientes categorías
de instrucciones:
Sentencias de Control en C#
Hay tres categorías de sentencias de control en C#: Las instrucciones de selección, que son los if y
switch, las instrucciones de iteración o ciclos, que consisten en el for, while, do-while y los bucles
foreach, y las instrucciones de salto, que incluyen break, continue, goto, return y throw. Explicaremos
cada uno de ellos a excepción del throw que forma parte de un mecanismo de excepción que lo
postearemos después.
La Sentencia if
if (condición) sentencia;
else sentencia;
- Pág. 1 de 24 -
Psy3com - Cuentos de terror
donde los objetivos de el if y el else son simples sentencias o declaraciones. La cláusula else es
opcional. Los objetivos de ambos el if y el else puede ser un bloque se sentencias (recuerde que los
bloques de sentencia en C# van entre llaves.
if (condición)
{
secuencia de expresiones
}
else
{
secuencia de expresiones
}
Si la expresión de condición es verdadera, se ejecutarán las secuencias de expresiones del if, en caso contrario
si existe la parte del else, estas serán ejecutadas. No se ejecutarán las dos al mismo tiempo. La expresión
Probando –5 : Negativo
Probando –4 : Negativo
Probando –3 : Negativo
Probando –2 : Negativo
Probando –1 : Negativo
Probando 0 : Positivo
Probando 1 : Positivo
- Pág. 2 de 24 -
Psy3com - Cuentos de terror
Probando 2 : Positivo
Probando 3 : Positivo
Probando 4 : Positivo
Probando 5 : Positivo
If anidados
Las instrucciones if pueden estar anidadas, es decir un if dentro de otro if. Esto es muy común en la
programación diaria. Por ejemplo la siguiente instrucción muestra un if anidado
if (i == 10)
{
if (j < 20)
a = b;
if (k > 100)
c = d;
else // este else se refiere al if(k>100)
a = c;
}
else
a = d; // este else se refiere al if( i == 10)
La escalera if-eslse-if
Una estructura común en programación es la escalera if-else-if. Esto luciría de la siguiente manera:
if (condición)
instruccion;
else if (condición)
instrucción;
else if (condición)
instucción;
- Pág. 3 de 24 -
Psy3com - Cuentos de terror
.
.
.
else
instrucción;
Las expresiones condicionales son evaluadas de arriba hacia abajo. Tan pronto como la condición
verdadera se encuentra, la instrucción o instrucciones asociadas son ejecutadas. y el resto de la escalera es
omitido. Si no se encuentra una condición verdadera la clausula else es ejecutada. En este caso la
claúsula else funciona como una expresión default. Si no existiera una cláusula else y ninguna condición
es verdadera, no se tomaría ninguna acción.
- Pág. 4 de 24 -
Psy3com - Cuentos de terror
La instrucción Switch
La segunda de las instrucciones de selección en C # es switch. El switch proporciona una rama múltiple
de selección, por lo tanto, permite a un programa seleccionar entre varias alternativas. Funciona así: El
valor de una expresión se prueba sucesivamente con una lista de las constantes. Cuando se encuentra una
coincidencia, la secuencia de instrucciones asociada con esa concordancia es ejecutado. La forma general
de la sentencia switch es:
switch(expresión)
{
case constant1:
statement sequence
break;
case constant2:
statement sequence
break;
case constant3:
statement sequence
break;
.
.
.
default:
statement sequence
break;
}
La expresión switch debe ser de un tipo entero, como char, byte, short o int, del un tipo de enumeración, o
de tipo cadena. Otras expresiones no están permitidas, como por ejemplo las de punto flotante. Con
frecuencia, la expresión de control del switch es simplemente una variable. En el caso de las constantes
deben ser de un tipo compatible con la expresión. No pueden haber dos constantes con el mismo valor en
la instrucción. La secuencia por defecto ( default ) se ejecuta si ningún caso (case) la expresión coincide
con la expresión constante. el valor por defecto es opcional, si no está presente, ninguna acción se lleva a
cabo si no hay coincidencias. Cuando un coincidencia es encontrada, las instrucciones asociadas a ese
case se ejecutan hasta que la rotura (break) se encuentra
- Pág. 5 de 24 -
Psy3com - Cuentos de terror
i es cero
i es dos
i es tres
i es cuatro
i es cinco o más
i es cinco o más
i es cinco o más
i es cinco o más
i es cinco o más
i es cinco o más
Las sentencias switch también pueden ser anidadas al igual que el if.
- Pág. 6 de 24 -
Psy3com - Cuentos de terror
El ciclo for
El instrucción for es una de las sentencias más poderosas y flexibles para los ciclos. En su forma general
la instrucción para repetir una simple instrucción es:
La Inicialización es normalmente una sentencia de asignación que fija el valor inicial de la variable que
controlará la iteraciones en el ciclo, actuando como contador. La condición es una expresión booleana
que determina si el ciclo se repetirá. La expresión iteración define la cantidad por la cual la variable de
control cambia cada vez que el ciclo es repetido. Nótese que cada expresión del for debe ser separado por
punto y coma. El ciclo for se repite mientras la condición es verdadera. Una vez que la condición llega a
ser falsa el ciclo se detiene y se sigue ejecutando la siguiente sentencia después del bloque for. El ciclo
puede iniciar de forma positiva o negativa e incrementar los valores en cualquier cantidad entera. Por
ejemplo el siguiente programa imprime los números del –100 al 100 con incrementos de –5
Algo importante de recalcar es que la condición se evalúa siempre en la parte superior del for. Esto significa que
el código dentro del ciclo for puede no ejecutarse si la condición es falsa desde el inicio. Por ejemplo:
int count;
for(count=10; count < 5; count++)
x += count; // Esta instrucción nunca se ejecutará
- Pág. 7 de 24 -
Psy3com - Cuentos de terror
Note que en los ejemplos anteriores la parte de la inicialización, es decir, donde se define el contador del ciclo, la
variable utilizada x = 100, se asume que ya fue declarada anteriormente como una variable del tipo entero. Esto
En el ejemplo anterior se suman los números del 1 al 100. La variable i se ha declarado e inicializado dentro del
ciclo.
El ciclo infinito
Usted puede crear un ciclo infinito (un ciclo que nunca termina) usando el for dejando la expresión de
condición vacía. Por ejemplo :
En C#, el cuerpo asociado con el ciclo for puede ser vacío. Esto es porque un el cuerpo vacío de un for es
sintácticamente válido. Los ciclos sin cuerpo son muy útiles. Por ejemplo para el programa usado para
sumar los números del 1 al 100 podemos resumirlo como se muestra a continuación:
- Pág. 8 de 24 -
Psy3com - Cuentos de terror
class Empty3 {
static void Main() {
int i;
int sum = 0;
// Suma los números del 1 al 100.
for(i = 1; i <= 5; sum += i++) ;
Console.WriteLine("La Suma es " + sum);
}
}
En este caso la instrucción de la suma se hace dentro de la instrucción for. ( sum += i++), aquí se acumula
el valor de i a la variable sum y además se incrementa la variable. Fíjese además que al terminar la linea
del for se colocaron el punto y como para definir que no hay cuerpo,
El ciclo while
Otro ciclo dentro del C# es el while. La forma general del while es:
donde sentencia puede ser una simple sentencia o un bloque de sentencias y condición define la condición
que controla el ciclo y puede ser cualquier expresión booleana válida. Las sentencias son ejecutadas
mientras la condición es verdadera. Cuando la condición llega a ser falsa, el control del programa pasa a
la línea inmediata que sigue el ciclo (si son más de una sentencias se debe usar un bloque con llaves para
que el while sepa que tiene que hacer todas las instrucciones en cada vuelta del ciclo).
- Pág. 9 de 24 -
Psy3com - Cuentos de terror
Número : 435679
Magnitud : 6
El ciclo trabaja de la siguiente manera: El valor de num es examinado. Si num es mayor que 0, la
variable mag es incrementada y num es divido entre 10. Mientras el valor num sea mayor que 0 el ciclo
se repite. Cuando num es igual a cero el ciclo se detiene y mag contiene el orden (cantidad de dígitos ) del
valor original.
El ciclo do-while
El tercer ciclo del C# es el ciclo do-while. A diferencia del ciclo for y el ciclo while, en los cuales la
condición es examinada y evaluada al inicio del ciclo, el ciclo do-while chequea la condición al final del
ciclo. Esto significa que el ciclo do-while siempre se ejecutará al menos una vez. La forma general del
ciclo do-while es la siguiente:
do {
sentencias;
} while(condición)
Las llaves no son necesarias si solo hay una sentencia, pero siempre es bueno tenerlas para que la
estructura sea más legible.
Por ejemplo el siguiente programa muestra como se imprimen los números en orden inverso mediante un
ciclo do-while
- Pág. 10 de 24 -
Psy3com - Cuentos de terror
Number: 198
Number in reverse order: 891
El ciclo foreach
El ciclo foreach recorre todos los elementos de una colección. Una colección es un grupo de objetos. C#
define varios tipos de colecciones, una de las cuales son los Arreglos o Matrices. Examinaremos
posteriormente el ciclo foreach cuando describamos los arreglos.
- Pág. 11 de 24 -
Psy3com - Cuentos de terror
Es posible forzar una salida inmediata del ciclo, sin pasar por el resto de código en el cuerpo del ciclo y la
prueba condición del ciclo,usando la instrucción break. Cuando el ciclo encuentra la instrucción break, el
ciclo es terminado, y el control del programa se pasa a la siguiente instrucción después del ciclo. Aquí un
ejemplo de su uso.
Usando continue
Es posible forzar una iteración temprana de un ciclo, sin pasar por la estructura del bucle de control
normal. Esto se logra utilizando continue. La sentencia continue obliga a la siguiente iteración de la ciclo
que tendrá lugar, saltándose cualquier código en el medio. Por lo tanto, continue es esencialmente el
complemento de break. Por ejemplo, el siguiente programa utiliza continue ayudando a imprimir los
números pares entre 0 y 100.
// Usar continue.
using System;
class ContDemo {
static void Main() {
// Imprimir número pares del 0 al 100.
for(int i = 0; i <= 100; i++) {
if((i%2) != 0) continue; // iterate
Console.WriteLine(i);
}
}
}
- Pág. 12 de 24 -
Psy3com - Cuentos de terror
Nótese que en el programa anterior se evalúa si el residuo de la división del número almacenado en la
variable i entre 2 es diferente de 0 se fuerza la siguiente iteración, si el valor es cero (el número es par) se
imprime el valor del número.
La instrucción return
Esta instrucción muy usada en los programas de C# se utiliza para salir de un método. Este también
puede ser usado para regresar un valor.
La sentencia goto
El goto es una sentencia de salto incondicional en C#. Cuando se encuentra el programa salta a una
localización definida por el goto. La sentencia cayó en desgracia con muchos programadores años atrás,
ya que fomentó la creación de código spaguetti. Sin embargo, el goto es todavía usado en ocasiones y de
manera eficiente. No se debe juzgar la forma de programar de algunos pero si se puede reducir su uso es
mejor. Un ejemplo de como se utilizaría sería el siguiente fragmento de código. Note que el goto
requiere siempre de un label que funciona como un identificador válido de C#.
x = 1;
loop1:
x++;
if(x < 100) goto loop1;
- Pág. 13 de 24 -
Psy3com - Cuentos de terror
Estructuras de control
Las instrucciones condicionales son instrucciones que permiten ejecutar bloques de instrucciones sólo
si se da una determinada condición. En los siguientes subapartados de este epígrafe se describen cuáles
son las instrucciones condicionales disponibles en C#
Instrucción if
if (<condición>){
<instruccionesIf>}
else{
<instruccionesElse>}
- Pág. 14 de 24 -
Psy3com - Cuentos de terror
using System;
class HolaMundoIf
{
public static void Main(String[] args)
{
if (args.Length > 0){
Console.WriteLine("Hola {0}!", args[0]);}
else{
Console.WriteLine("Hola mundo!");}
}
}
Si ejecutamos este programa sin ningún argumento veremos que el mensaje que se muestra es ¡Hola
Mundo!, mientras que si lo ejecutamos con algún argumento se mostrará un mensaje de bienvenida
personalizado con el primer argumento indicado.
Instrucción switch
La instrucción switch permite ejecutar unos u otros bloques de instrucciones según el valor de una
cierta expresión. Su estructura es:
switch (<expresión>)
{
case <valor1>: <bloque1>
<siguienteAcción>
case <valor2>: <bloque2>
<siguienteAcción>
...
default: <bloqueDefault>
<siguienteAcción>
}
- Pág. 15 de 24 -
Psy3com - Cuentos de terror
Los valores indicados en cada rama del switch han de ser expresiones constantes que produzcan
valores de algún tipo básico entero, de una enumeración, de tipo char o de tipo string. Además, no puede
haber más de una rama con el mismo valor.
En realidad, aunque todas las ramas de un switch son opcionales siempre se ha de incluir al menos una.
Además, la rama default no tiene porqué aparecer la última si se usa, aunque es recomendable que lo
haga para facilitar la legibilidad del código.
El elemento marcado como <siguienteAcción> colocado tras cada bloque de instrucciones indica qué
es lo que ha de hacerse tras ejecutar las instrucciones del bloque que lo preceden. Puede ser uno de estos
tres tipos de instrucciones:
Si es un goto case indica que se ha de seguir ejecutando el bloque de instrucciones asociado en el switch a la
rama del <valori> indicado, si es un goto default indica que se ha de seguir ejecutando el bloque de instrucciones
de la rama default, y si es un break indica que se ha de seguir ejecutando la instrucción siguiente al switch.
using System;
class HolaMundoSwitch
{
public static void Main(String[] args)
{
if (args.Length > 0)
switch(args[0])
{
case "José":
Console.WriteLine("Hola José. Buenos días");
break;
case "Paco":
Console.WriteLine("Hola Paco. Me alegro de
verte");
break;
default:
Console.WriteLine("Hola {0}", args[0]);
break;
}
else
Console.WriteLine("Hola Mundo");
}
}
- Pág. 16 de 24 -
Psy3com - Cuentos de terror
Este programa reconoce ciertos nombres de personas que se le pueden pasar como argumentos al lanzarlo
y les saluda de forma especial. La rama default se incluye para dar un saludo por defecto a las personas no
reconocidas.
Para los programadores habituados a lenguajes como C++ es importante resaltarles el hecho de que, a
diferencia de dichos lenguajes, C# obliga a incluir una sentencia break o una sentencia goto case al final
de cada rama del switch para evitar errores comunes y difíciles de detectar causados por olvidar incluir
break; al final de alguno de estos bloques y ello provocar que tras ejecutarse ese bloque se ejecute
también el siguiente.
Instrucciones iterativas
Las instrucciones iterativas son instrucciones que permiten ejecutar repetidas veces una instrucción o
un bloque de instrucciones mientras se cumpla una condición. Es decir, permiten definir bucles donde
ciertas instrucciones se ejecuten varias veces. A continuación se describen cuáles son las instrucciones de
este tipo incluidas en C#.
Instrucción while
La instrucción while permite ejecutar un bloque de instrucciones mientras se de una cierta instrucción.
Su sintaxis de uso es:
while (<condición>)
{
<instrucciones>
}
using System;
class HolaMundoWhile
{
public static void Main(String[] args)
{
int actual = 0;
- Pág. 17 de 24 -
Psy3com - Cuentos de terror
if (args.Length > 0)
while (actual < args.Length)
{
Console.WriteLine("¡Hola {0}!",
args[actual]);
actual = actual + 1;
}
else
Console.WriteLine("¡Hola mundo!");
}
}
En este caso, si se indica más de un argumento al llamar al programa se mostrará por pantalla un
mensaje de saludo para cada uno de ellos. Para ello se usa una variable actual que almacena cuál es el
número de argumento a mostrar en cada ejecución del while. Para mantenerla siempre actualizada lo que
se hace es aumentar en una unidad su valor tras cada ejecución de las <instrucciones> del bucle.
Por otro lado, dentro de las <instrucciones> de un while pueden utilizarse las siguientes dos
instrucciones especiales:
break;: Indica que se ha de abortar la ejecución del bucle y continuarse ejecutando por la instrucción
siguiente al while.
continue;: Indica que se ha de abortar la ejecución de las <instrucciones> y reevaluarse la <condición> del
bucle, volviéndose a ejecutar las <instrucciones> si es cierta o pasándose a ejecutar la instrucción
siguiente al while si es falsa.
Instrucción do...while
do {
<instrucciones>
} while(<condición>);
La única diferencia del significado de do...while respecto al de while es que en vez de evaluar primero
la condición y ejecutar <instrucciones> sólo si es cierta, do...while primero ejecuta las <instrucciones> y
luego mira la <condición> para ver si se ha de repetir la ejecución de las mismas. Por lo demás ambas
instrucciones son iguales, e incluso también puede incluirse break; y continue; entre las <instrucciones>
del do...while.
do ... while está especialmente destinado para los casos en los que haya que ejecutar las
<instrucciones> al menos una vez aún cuando la condición sea falsa desde el principio, como ocurre en el
siguiente ejemplo:
- Pág. 18 de 24 -
Psy3com - Cuentos de terror
using System;
class HolaMundoDoWhile
{
public static void Main()
{
String leído;
do
{
Console.WriteLine("Clave: ");
leído = Console.ReadLine();
}
while (leído != "José");
Console.WriteLine("Hola José");
}
}
Este programa pregunta al usuario una clave y mientras no introduzca la correcta (José) no continuará
ejecutándose. Una vez que introducida correctamente dará un mensaje de bienvenida al usuario.
Instrucción for
La instrucción for es una variante de while que permite reducir el código necesario para escribir los
tipos de bucles más comúnmente usados en programación. Su sintaxis es:
Con <modificación> pasa algo similar, ya que puede incluirse código que nada tenga que ver con
modificaciones pero en este caso no se pueden incluir definiciones de variables.
- Pág. 19 de 24 -
Psy3com - Cuentos de terror
Como en el resto de instrucciones hasta ahora vistas, en <instrucciones> puede ser tanto una única
instrucción como un bloque de instrucciones. Además, las variables que se definan en <inicialización>
serán visibles sólo dentro de esas <instrucciones>.
La siguiente clase es equivalente a la clase HolaMundoWhile ya vista solo que hace uso del for para
compactar más su código:
using System;
class HolaMundoFor
{
public static void Main(String[] args)
{
if (args.Length > 0)
for (int actual = 0; actual < args.Length;
actual++) {
Console.WriteLine("¡Hola {0}!",
args[actual]);
}
else
Console.WriteLine("¡Hola mundo!");
}
}
Al igual que con while, dentro de las <instrucciones> del for también pueden incluirse instrucciones
continue; y break; que puedan alterar el funcionamiento normal del bucle.
Instrucción foreach
La instrucción foreach es una variante del for pensada especialmente para compactar la escritura de
códigos donde se realice algún tratamiento a todos los elementos de una colección, que suele un uso muy
habitual de for en los lenguajes de programación que lo incluyen. La sintaxis que se sigue a la hora de
escribir esta instrucción foreach es:
El significado de esta instrucción es muy sencillo: se ejecutan <instrucciones> para cada uno de los
elementos de la <colección> indicada. <elemento> es una variable de sólo lectura de tipo <tipoElemento>
que almacenará en cada momento el elemento de la colección que se esté procesando y que podrá ser
accedida desde <instrucciones>.
Es importante señalar que <colección> no puede valer null porque entonces saltaría una excepción de
tipo System.NullReferenceException, y que <tipoElemento> ha de ser un tipo cuyos objetos puedan
almacenar los valores de los elementos de <colección>
- Pág. 20 de 24 -
Psy3com - Cuentos de terror
En tanto que una tabla se considera que es una colección, el siguiente código muestra cómo usar for
para compactar aún más el código de la clase HolaMundoFor anterior:
using System;
class HolaMundoForeach
{
public static void Main(String[] args)
{
if (args.Length > 0)
foreach(String arg in args) {
Console.WriteLine("¡Hola {0}!", arg);
}
else
Console.WriteLine("¡Hola mundo!");
}
}
Las tablas multidimensionales también pueden recorrerse mediante el foreach, el cual pasará por sus
elementos en orden tal y como muestra el siguiente fragmento de código:
1
2
3
4
En general, se considera que una colección es todo aquel objeto que implemente las interfaces
IEnumerable o IEnumerator del espacio de nombres System.Collections de la BCL, que están
definidas como sigue:
interface IEnumerable
{
[C#]
IEnumerator GetEnumerator();
}
interface IEnumerator
{
[C#]
object Current {get;}
[C#]
- Pág. 21 de 24 -
Psy3com - Cuentos de terror
bool MoveNext();
[C#]
void Reset();
}
El método MoveNext() se ha de implementar de modo que haga que el enumerador pase a apuntar al
siguiente elemento de la colección y devuelva un booleano que indique si tras avanzar se ha alcanzado el
final de la colección.
Otra forma de conseguir que foreach considere que un objeto es una colección válida consiste en hacer
que dicho objeto siga el patrón de colección. Este patrón consiste en definir el tipo del objeto de modo
que sus objetos cuenten con un método público GetEnumerator() que devuelva un objeto no nulo que
cuente con una propiedad pública llamada Current que permita leer el elemento actual y con un método
público bool MoveNext() que permita cambiar el elemento actual por el siguiente y devuelva false sólo
cuando se haya llegado al final de la colección.
using System;
using System.Collections;
class Patron
{
private int actual = -1;
public Patron GetEnumerator()
{
return this;
}
- Pág. 22 de 24 -
Psy3com - Cuentos de terror
}
}
class Interfaz:IEnumerable,IEnumerator
{
private int actual = -1;
public object Current
{
get {return actual;}
}
Nótese que en realidad en este ejemplo no haría falta implementar IEnumerable, puesto que la clase
Interfaz ya implementa IEnumerator y ello es suficiente para que pueda ser recorrida mediante foreach.
Por ejemplo, si en el ejemplo anterior sustituimos en el último foreach el <tipoElemento> indicado por
Patrón, el código seguirá compilando pero al ejecutarlo saltará una excepción
System.InvalidCastException. Sin embargo, si la sustitución se hubiese hecho en el penúltimo foreach,
- Pág. 23 de 24 -
Psy3com - Cuentos de terror
entonces el código directamente no compilaría y se nos informaría de un error debido a que los objetos
int no son convertibles en objetos Patrón.
También hay que tener en cuenta que la comprobación de tipos que se realiza en tiempo de ejecución
si el objeto sólo implementó la interfaz IEnumerable es muy estricta, en el sentido de que si en el
ejemplo anterior sustituimos el <tipoElemento> del último foreach por byte también se lanzará la
excepción al no ser los objetos de tipo int implícitamente convertibles en bytes sino sólo a través del
operador () Sin embargo, cuando se sigue el patrón de colección las comprobaciones de tipo no son tan
estrictas y entonces sí que sería válido sustituir int por byte en <tipoElemento>.
El problema de sólo implementar el patrón colección es que este es una característica propia de C# y
con las instrucciones foreach (o equivalentes) de lenguajes que no lo soporten no se podría recorrer
colecciones que sólo siguiesen este patrón. Una solución en estos casos puede ser hacer que el tipo del
objeto colección implemente tanto la interfaz IEnumerable como el patrón colección. Obviamente esta
interfaz debería implementarse explícitamente para evitarse conflictos derivados de que sus miembros
tengan signaturas coincidentes con las de los miembros propios del patrón colección.
- Pág. 24 de 24 -