Ejercicio: Inicio y detección de excepciones en una aplicación de consola de C#

Completado

En este ejercicio, desarrollará un bloque de código try y una cláusula catch en las instrucciones de nivel superior, creará e iniciará excepciones en el método MakeChange y, luego, completará el bloque de código catch mediante un objeto de excepción. Durante este ejercicio se realizarán las tareas siguientes:

  1. Actualizar instrucciones de nivel superior: implemente un patrón try-catch en las instrucciones de nivel superior. El bloque de código try contendrá la llamada a MakeChange.
  2. Actualizar el método MakeChange: cree e inicie excepciones para problemas de "Insuficiente hasta" y "Pago insuficiente".
  3. Actualice el bloque de código catch para usar las propiedades de la excepción iniciada.
  4. Prueba de comprobación: realice pruebas de comprobación del código que desarrolle en este ejercicio.

Agregar un patrón try-catch a las instrucciones de nivel superior

En esta tarea, encerrará la llamada al método MakeChange dentro de una instrucción try y creará la cláusula catch correspondiente.

  1. Asegúrese de que el archivo Program.cs esté abierto en el Editor de Visual Studio Code.

  2. Busque las siguientes líneas de código:

    // MakeChange manages the transaction and updates the till 
    string transactionMessage = MakeChange(itemCost, cashTill, paymentTwenties, paymentTens, paymentFives, paymentOnes);
    
    // Backup Calculation - each transaction adds current "itemCost" to the till
    if (transactionMessage == "transaction succeeded")
    {
        Console.WriteLine($"Transaction successfully completed.");
        registerCheckTillTotal += itemCost;
    }
    else
    {
        Console.WriteLine($"Transaction unsuccessful: {transactionMessage}");
    }
    
  3. Deténgase un minuto a considerar la finalidad de este código.

    Observe que MakeChange devuelve un valor de cadena. El valor devuelto se asigna a una variable llamada transactionMessage. Si transactionMessage es igual a "transacción correcta", el costo del artículo comprado se agrega a registerCheckTillTotal. La variable registerCheckTillTotal se usa para comprobar el balance de caja calculado por el método MakeChange.

  4. Para incluir la llamada al método MakeChange en un bloque de código de instrucción try, actualice el código de la siguiente manera:

    try
    {
        // MakeChange manages the transaction and updates the till 
        string transactionMessage = MakeChange(itemCost, cashTill, paymentTwenties, paymentTens, paymentFives, paymentOnes);
    }
    
  5. Agregue la cláusula catch siguiente después del bloque de código de instrucción try:

    catch
    {
    }
    

    Cuando haya creado e iniciado las excepciones, finalizará el desarrollo de la cláusula catch.

Creación e inicio de excepciones en el método MakeChange

En esta tarea, actualizará MakeChange para crear y generar excepciones personalizadas cuando no se pueda completar una transacción.

El método MakeChange incluye dos problemas que deben dar lugar a excepciones:

  • Problema de pago insuficiente: este problema se produce cuando el cliente ofrece un pago menor que el costo del artículo. Si el cliente no ha ofrecido un pago suficiente, MakeChange debe iniciar una excepción.

  • Problema de caja insuficiente: este problema se produce cuando la caja no contiene los billetes necesarios para producir el cambio exacto. Si la caja no puede realizar el cambio exacto, MakeChange debería iniciar una excepción.

  1. Desplácese hacia abajo hasta el método MakeChange.

  2. Busque las siguientes líneas de código:

    if (changeNeeded < 0)
        transactionMessage = "Not enough money provided.";
    
  3. Deténgase un minuto a considerar el problema que este código soluciona.

    Si changeNeeded es menor que cero, significa que el cliente no ha proporcionado suficiente dinero para cubrir el precio de compra del artículo que va a adquirir. El precio de compra y el dinero proporcionado por el cliente son parámetros del método MakeChange. El método no puede completar la transacción cuando el cliente no proporciona suficiente dinero. En otras palabras, se produce un error en la operación.

    Hay dos tipos de excepción que parecen coincidir con estas condiciones:

    • InvalidOperationException: una excepción InvalidOperationException solo se debe iniciar cuando las condiciones de funcionamiento de un método no admitan la finalización correcta de una llamada de método determinada. En este caso, los parámetros proporcionados al método establecen las condiciones de funcionamiento.
    • ArgumentOutOfRangeException: una excepción ArgumentOutOfRangeException solo se debe iniciar cuando el valor de un argumento está fuera del intervalo de valores permitido definido por el método invocado. En este caso, el dinero proporcionado debe ser mayor que el costo del artículo.

    Cualquier tipo de excepción podría funcionar, pero InvalidOperationException es una coincidencia ligeramente mejor en el contexto de esta aplicación.

  4. Actualice el código de la siguiente manera:

    if (changeNeeded < 0)
        throw new InvalidOperationException("InvalidOperationException: Not enough money provided to complete the transaction.");
    
  5. Desplácese hacia abajo para buscar las siguientes líneas de código:

    if (changeNeeded > 0)
        transactionMessage = "Can't make change. Do you have anything smaller?";
    
  6. Deténgase un minuto a considerar el problema que este código soluciona.

    Si changeNeeded es mayor que cero después de los bucles while que preparan el cambio, es que la caja se ha quedado sin billetes con los que dar el cambio. El método no puede completar la transacción cuando la caja no tiene los billetes necesarios para dar el cambio. En otras palabras, se produce un error en la operación.

    La excepción InvalidOperationException se debe usar para crear la excepción.

  7. Actualice el código de la siguiente manera:

    if (changeNeeded > 0)
        throw new InvalidOperationException("InvalidOperationException: The till is unable to make the correct change.");
    

Completar el bloque de código catch

En esta tarea, actualizará la cláusula catch para detectar un tipo de excepción específico.

  1. Desplácese hacia arriba por encima del método MakeChange y busque el código siguiente:

    catch
    {
    }    
    
  2. Para detectar el tipo de excepción iniciada en el método MakeChange, actualice el código de la siguiente manera:

    catch (InvalidOperationException e)
    {
        Console.WriteLine($"Could not complete transaction: {e.Message}");
    }    
    

    El objeto de excepción InvalidOperationException que se inicia en MakeChange se detectará, pero no así otros tipos de excepción. Puesto que no está preparado para controlar otros tipos de excepción, es importante dejar que se detecten más abajo en la pila de llamadas. Si sabe que se esperan otros tipos de excepción dentro de MakeChange, puede agregar más cláusulas catch.

  3. Use el menú Archivo para guardar las actualizaciones.

Convertir el método MakeChange de "string" a "void" y acceder a las propiedades de excepción

En esta tarea, actualizará MakeChange para que sea de tipo void y, luego, usará las propiedades de excepción para comunicar los detalles del problema al usuario.

  1. Desplácese a la parte superior del método MakeChange.

  2. Para convertir el método MakeChange del tipo string al tipo void, actualice el código de la siguiente manera:

    static void MakeChange(int cost, int[] cashTill, int twenties, int tens = 0, int fives = 0, int ones = 0)
    
  3. Elimine la siguiente declaración de variable:

    string transactionMessage = "";
    
  4. Desplácese hasta la parte inferior del método MakeChange.

  5. Elimine las líneas de código siguientes:

    if (transactionMessage == "")
        transactionMessage = "transaction succeeded";
    
    return transactionMessage;
    
  6. Desplácese hasta las instrucciones de nivel superior y busque el bloque de código try.

  7. Actualice el bloque de código try de la siguiente manera:

    try
    {
        // MakeChange manages the transaction and updates the till 
        MakeChange(itemCost, cashTill, paymentTwenties, paymentTens, paymentFives, paymentOnes);
    
        Console.WriteLine($"Transaction successfully completed.");
        registerCheckTillTotal += itemCost;
    }
    
  8. Busque y elimine las líneas de código siguientes:

    // Backup Calculation - each transaction adds current "itemCost" to the till
    if (transactionMessage == "transaction succeeded")
    {
        Console.WriteLine($"Transaction successfully completed.");
        registerCheckTillTotal += itemCost;
    }
    else
    {
        Console.WriteLine($"Transaction unsuccessful: {transactionMessage}");
    }
    
    

    Los bloques de código try y catch ahora comunican al usuario los mensajes de "éxito" y "error" de la transacción. Dado que la propiedad Message de la excepción describe el problema, una única instrucción Console.WriteLine() soluciona ambos problemas. Después de estas actualizaciones, el código es más fácil de leer y mantener.

  9. Use el menú Archivo para guardar las actualizaciones.

Comprobar el trabajo

En esta tarea, ejecutará la aplicación y comprobará que el código actualizado funciona según lo previsto.

  1. Desplácese hacia arriba para encontrar el bucle while en las instrucciones de nivel superior.

    Este bucle se usa para recorrer en iteración las transacciones.

  2. Busque el código siguiente unas líneas antes del inicio del bucle while.

    int transactions = 10;
    
    
  3. Actualice el número de transacciones a 40 de la forma siguiente:

    int transactions = 40;
    
    
  4. Busque la siguiente línea de código dentro del bucle while.

    int itemCost = valueGenerator.Next(2, 20);
    
    
  5. Actualice el generador de números aleatorios itemCost de la siguiente manera:

    int itemCost = valueGenerator.Next(2, 50);
    
    

    Este intervalo de costos coincide mejor con los artículos que los clientes van a comprar.

  6. Use el menú Archivo para guardar las actualizaciones.

  7. En el menú Ejecutar, seleccione Iniciar depuración.

  8. Revise la salida en el panel TERMINAL.

  9. Compruebe que se muestran los mensajes asociados a los dos tipos de excepción:

    El informe de transacciones debe incluir los siguientes mensajes "No se pudo completar la transacción":

    Customer is making a $42 purchase
             Using 2 twenty dollar bills
             Using 0 ten dollar bills
             Using 0 five dollar bills
             Using 0 one dollar bills
    Could not complete transaction: InvalidOperationException: Not enough money provided to complete the transaction.
    
    Customer is making a $23 purchase
             Using 2 twenty dollar bills
             Using 0 ten dollar bills
             Using 0 five dollar bills
             Using 1 one dollar bills
    Cashier prepares the following change:
             A five
             A five
             A one
             A one
    Could not complete transaction: InvalidOperationException: The till is unable to make change for the cash provided.
    
    

Enhorabuena, ha depurado la aplicación de caja registradora para corregir un problema con la lógica del código y ha actualizado la aplicación para usar las técnicas de control de excepciones adecuadas.

Nota

La salida notificada muestra que el balance de la caja registradora ya no es correcto. Hay errores de lógica adicionales en el código. Si está interesado en poner a prueba sus conocimientos sobre la depuración en Visual Studio Code, hay un módulo de proyectos de desafío.