Cargando...

Técnicas de depuración en C#

Aprende técnicas de depuración en C# con breakpoints y herramientas de análisis para detectar y corregir errores.

En el proceso de desarrollo de software, la depuración (debugging) es un proceso sistemático para analizar el comportamiento inesperado de un programa e identificar el código defectuoso. En C#, herramientas como Visual Studio y Visual Studio Code ofrecen potentes capacidades de depuración que permiten a los desarrolladores ejecutar el código paso a paso, inspeccionar valores de variables y analizar el flujo de ejecución.


Diferencia entre los modos Debug y Release

Los proyectos .NET tienen dos configuraciones principales de compilación:


// En Visual Studio, seleccionable en la barra superior:
// [Debug ▼] → [Release]

En modo Debug, el programa puede ejecutarse línea por línea, lo que permite un control total sobre el flujo del código.


Puntos de interrupción (Breakpoints)

Un breakpoint es un marcador que detiene la ejecución del programa en una línea específica. De esta manera, el programa se ejecuta hasta ese punto, permitiendo inspeccionar los valores actuales de las variables.


class Program
{
    static void Main()
    {
        int a = 5;
        int b = 0;
        int c = a / b; // Error: DivideByZeroException
        Console.WriteLine(c);
    }
}

En el ejemplo anterior, se puede colocar un breakpoint en la línea int c = a / b; para que el programa se detenga ahí y se puedan examinar los valores de a y b en la ventana “Locals”.


Comandos de ejecución paso a paso (Stepping)

Visual Studio ofrece varios atajos de teclado para ejecutar el código paso a paso:

Estas herramientas proporcionan un control completo del flujo del programa y permiten identificar con precisión dónde comienza el error.


Observación de variables (Watch y Autos)

Visual Studio permite monitorear los valores de las variables en tiempo real durante la depuración:

Al colocar el cursor sobre una variable, aparece una ventana emergente con su valor actual.


Uso de las ventanas Immediate y Watch

La ventana Immediate permite ejecutar código directamente durante la depuración. Con ella, puedes modificar valores de variables o probar expresiones sin reiniciar el programa.


// Ejemplo de la ventana Immediate:
// ? a + b
// ? myList.Count
// a = 25

Esto te permite probar cálculos o ajustar valores sin detener la aplicación.


Puntos de interrupción condicionales

A veces, no quieres que el programa se detenga en cada iteración, sino solo cuando se cumple una condición específica. Para ello se utilizan los breakpoints condicionales.


for (int i = 0; i < 100; i++)
{
    Console.WriteLine(i);
}

Después de agregar un breakpoint en este bucle, abre el menú “Conditions” y define la condición i == 50. El programa se detendrá únicamente cuando i sea igual a 50.


Configuración de excepciones

Desde el menú Debug → Windows → Exception Settings puedes especificar los tipos de excepciones para los que el programa debe detenerse. Por ejemplo, puedes configurarlo para detenerse solo en NullReferenceException o InvalidOperationException.

Esta función ayuda a evitar interrupciones innecesarias en aplicaciones complejas.


Depuración dentro de bloques Try / Catch

Incluso cuando los errores se capturan dentro de un bloque try / catch, Visual Studio puede detenerse en la línea exacta donde se produce la excepción si la opción “Break on User-Unhandled Exceptions” está habilitada.


try
{
    int[] arreglo = new int[3];
    arreglo[5] = 10; // IndexOutOfRangeException
}
catch (Exception ex)
{
    Console.WriteLine("Excepción capturada: " + ex.Message);
}

Esto te permite examinar el estado de la aplicación justo antes de que se produzca la excepción.


Uso de Debug.WriteLine()

El método Debug.WriteLine() escribe mensajes informativos en la ventana de salida (Output Window) durante la depuración. Es útil para registrar información en segundo plano sin alterar la salida de la consola.


using System.Diagnostics;

class Program
{
    static void Main()
    {
        for (int i = 0; i < 3; i++)
        {
            Debug.WriteLine($"Paso {i} completado.");
        }
        Console.WriteLine("Programa finalizado.");
    }
}

Estos mensajes solo son visibles en modo Debug y no se ejecutan en modo Release.


Registro (Logging) y seguimiento de errores

La depuración no solo sirve para el análisis en tiempo real, sino también para el seguimiento a largo plazo de una aplicación. Para ello, se pueden utilizar bibliotecas de registro como Serilog, NLog o Microsoft.Extensions.Logging.


using Microsoft.Extensions.Logging;

class Program
{
    static void Main()
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder.AddConsole();
        });
        var logger = loggerFactory.CreateLogger<Program>();

        try
        {
            int a = 10, b = 0;
            int c = a / b;
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "¡Se ha producido un error!");
        }
    }
}

El registro permite rastrear errores no solo durante el desarrollo, sino también en entornos de producción.


Ejemplo: Depuración de inicio de sesión de usuario

El programa se detendrá en la línea donde coloques el punto de interrupción (breakpoint).

Punto de interrupción en líneas de código

El siguiente ejemplo muestra cómo depurar paso a paso un error en un formulario de inicio de sesión.


class LoginService
{
    public bool Login(string username, string password)
    {
        if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
            throw new ArgumentException("El nombre de usuario o la contraseña no pueden estar vacíos.");

        return username == "admin" && password == "1234";
    }
}

class Program
{
    static void Main()
    {
        var service = new LoginService();
        Console.Write("Nombre de usuario: ");
        string? u = Console.ReadLine();
        Console.Write("Contraseña: ");
        string? p = Console.ReadLine();

        try
        {
            bool result = service.Login(u, p);
            Console.WriteLine(result ? "Inicio de sesión exitoso" : "Credenciales inválidas");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}

Puedes colocar un punto de interrupción en cualquier línea e inspeccionar las variables paso a paso.

Depuración de líneas de código

Al colocar un punto de interrupción en la línea return, puedes inspeccionar los valores de username y password en tiempo real y analizar por qué la condición devuelve false.


Mejores prácticas


TL;DR

  • Depuración: El proceso de seguir paso a paso la ejecución del programa para encontrar errores.
  • Punto de interrupción (Breakpoint): Detiene la ejecución del código en una línea específica.
  • Watch & Immediate: Herramientas para observar variables y ejecutar código al instante.
  • Debug.WriteLine: Salida de registro específica para desarrolladores (solo en modo Debug).
  • Registro (Logging): Registra errores y eventos, útil en entornos de producción.
  • Puntos de interrupción condicionales: Detienen el depurador solo bajo ciertas condiciones, mejorando la eficiencia.

Artículos relacionados