Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

18 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 2 de julio de 2024
C#

Cuando en un bucle for necesitamos más de una variable de control, lo habitual es inicializarlas fuera del bucle y luego usarlas en su interior, por ejemplo, como en el siguiente código:

int j = 0;
for (int i = 0; i < 10 && j < 100; i++)
{
    Console.WriteLine($"i = {i}, j = {j}");
    j+= 10;
}

Sin embargo, C# permite declarar varias variables en la cláusula de inicialización del bucle for, separándolas por comas, de la misma forma que podemos introducir distintas operaciones de incremento. Por lo tanto, el código anterior se puede simplificar de la siguiente manera:

for (int i = 0, j = 0; i < 10 && j < 100; i++, j += 10)
{
    Console.WriteLine($"i = {i}, j = {j}");
}

De esta forma, además de lograr un código algo más conciso, es también más expresivo: dejamos claro que el único objetivo de j es ejercer como variable de control del bucle y no será posible acceder a ella desde fuera del mismo.

Sin embargo, esto sólo es válido para variables del mismo tipo. Si intentamos usar esta sintaxis con variables de distinto tipo, obtendremos errores de compilación:

// Intentamos inicializar directamente la variable decimal...
// CS0266: Cannot implicitly convert type 'decimal' to 'int'
for (int i = 0, j = 0.0m; i < 10 && j < 100; i++, j += 10)
{
    Console.WriteLine($"i = {i}, j = {j}");
}

// Bueno, indiquémosle explícitamente el tipo, a ver qué tal...
// CS1525: Invalid expression term 'decimal'
for (int i = 0, decimal j = 0.0m; i < 10 && j < 100; i++, j += 10)
{
    Console.WriteLine($"i = {i}, j = {j}");
}

// Quizás si usamos var, el compilador use el tipo correcto...
// CS0819: Implicitly-typed variables cannot have multiple declarators
for (var i = 0, j = 0.0m; i < 10 && j < 100; i++, j += 10)
{
    Console.WriteLine($"i = {i}, j = {j}");
}

Pues por más que lo hayamos intentado, no hay forma de declarar variables de distinto tipo en la cláusula de inicialización del bucle for.

La opción en este caso es utilizar tuplas, que es una opción moderna, concisa y flexible. Una primera aproximación podría ser la siguiente, donde declaramos una variable de control de tipo tupla y usamos sus elementos en el bucle:

for (var ctrl = (i: 0, j: 0.0m); ctrl.i < 10 && ctrl.j < 100; ctrl.i++, ctrl.j += 10)
{
    Console.WriteLine($"i = {ctrl.i}, j = {ctrl.j}");
}

Aunque funciona, se ve demasiado farragoso. Afortunadamente, C# permite usar deconstruccion para simplificar el código; basta con declarar la tupla en la cláusula de inicialización del bucle y usar las variables directamente en el resto de cláusulas o cuerpo del bucle:

for ((int i, decimal j) = (0, 0.0m); i < 10 && j < 100; i++, j += 10)
{
    Console.WriteLine($"i = {i}, j = {j}");
}

O también, de forma algo más concisa, podemos dejar que el compilador infiera los tipos de las variables:

for (var (i, j) = (0, 0.0m); i < 10 && j < 100; i++, j += 10)
{
    Console.WriteLine($"i = {i}, j = {j}");
}

Publicado en Variable not found.

Aún no hay comentarios, ¡sé el primero!