How do I skip the "Finally" block, in C#, when the exception is generated?

Asked

Viewed 362 times

0

If the exception is generated, I want to know if there is a way to "skip" the execution of the block finally. If there is no exception, the finally perform normally. With the goto didn’t work.

Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Calculadora
{
    class Program
    {
        static void Main(string[] args)
        {
            double n1, n2, multiplicacao;
            try
            {
                Console.Write("Digite o primeiro numero.\n");
                n1 = double.Parse(Console.ReadLine());
                Console.Write("Digite o segundo numero.\n");
                n2 = double.Parse(Console.ReadLine());
                multiplicacao = n1 * n2;

                Console.WriteLine("\nResultado...\n");
                Console.WriteLine(n1+" * "+n2+" = " + multiplicacao);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Erro ao tentar fazer a conta.");
                goto pular;
            }
            finally
            {
                Console.WriteLine("\nO finally foi executado...");
            }
            pular:
            Console.WriteLine("\n\n O finally nao foi executou.");
        }
    }
}
  • 2

    It doesn’t make much sense that you want it. The finally is to ensure that the routine within it is always executed if there is an exception and this exception stops the flow and causes it to exit the method where the exception occurred preventing an important code to be executed. With the finally you can give guarantees that it will be executed. If you want to run q on it, just don’t declare the block finally and put your routine below the catch for its execution (without guarantees) .

4 answers

6

It doesn’t make any sense that what you’re wanting, Finally, is for you to perform the necessary logics in case the block try whether or not you can do your job.

For example

You open the connection with SQL and then during a query the connection drops will be generated an exception, but given the right or error you need to close the connection with SQL, then you put this logic on finally.

If you want to skip the Finally simply remove it.

  • I know it doesn’t make sense. It’s just a demonstration for another need. It’s just that I have to use a similar logic in another implementation, in college. Because I put this simple example.

  • Thank you. Buddy, I think my question was wrong. I want the application to be finished so it won’t run Finally.

6

This code has several problems, some are errors, others is just bad style issue:

1 - This problem need not deal with exception. It needs to check the error and give due treatment. Use TryParse() and be happy with no exceptions.

2 - If you are going to use exception, put in Finally only what should be executed always. What should not be executed if generating an exception, put out.

3 - If you capture an exception, make it as specific as possible, just use Exception if you have an excellent justification.

4 - If you will not use the exception variable, do not use it.

5 - Only declare the variable where you will use it, do not pre-declarations that do not bring benefits.

6 - It is not the end of the world in this case, but avoid concatenations of string and prefer interpolation of string.

7 - I made other almost cosmetic improvements.

using static System.Console;

namespace Calculadora {
    public class Program {
        public static void Main(string[] args) {
            WriteLine("Digite o primeiro numero.");
            if (!double.TryParse(ReadLine(), out var n1)) { //dá para fazer genérico
                WriteLine("Dado digitado inválido");
                return;
            }
            WriteLine("Digite o segundo numero.");
            if (!double.TryParse(ReadLine(), out var n2)) { //reaproveite e não é necessário
                WriteLine("Dado digitado inválido");
                return;
            }
            double multiplicacao = n1 * n2;
            WriteLine("Resultado...");
            WriteLine($"{n1} * {n2} = {multiplicacao}");
            WriteLine("Tudo foi executado...");
        }
    }
}

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

This code requires C# 7, but with a small modification can run in C# 6 and with little else can run in all versions.

If you still want to insist on the exception and even to answer the question, what you want is not to skip the finally is that there is no finally. The completion mechanism of the attempt is that the code must be executed in any case. If you want it to be skipped when you make the exception, then it should stay out of the whole block try-catch-finally. Just like that. You can do:

using System;
using static System.Console;

namespace Calculadora {
    public class Program {
        public static void Main(string[] args) {
            try {
                WriteLine("Digite o primeiro numero.");
                double n1 = double.Parse(ReadLine());
                WriteLine("Digite o segundo numero.");
                double n2 = double.Parse(ReadLine());
                double multiplicacao = n1 * n2;
                WriteLine("Resultado...");
                WriteLine($"{n1} * {n2} = {multiplicacao}");
            } catch (Exception) { //só para efeitos de teste, caso contrário não capture Exception
                WriteLine("Erro ao tentar fazer a conta."); //na prática agora nunca acontecerá a exceção
                WriteLine("O finally nao foi executou.");
                return;
            }
            WriteLine("Tudo foi executado...");
        }
    }
}

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

Note that there is another exception occurring. I think it is something momentary in . NET Fiddle anyway shows how problematic it is to capture Exception, take what you don’t expect.

I reinforce that all this is wrong, take the first.

If you want to finish a show and he’s not on Main() then in place of return should use the Environment.Exit(), unless you are in a Winforms application, then you should use the Application.Exit(). There are other variations for applications of other technologies (WPF, UWP, ASPNET, etc.), including if it is a test. There are cases that even other solutions are more suitable.

Besides the question doesn’t talk about finishing the application soon, it talks about skipping the catch.

5


Quoting the MSDN

Usually the instructions of a block finally are executed when the control leaves an instruction try. The transfer of control can occur as a result of the normal execution, of the execution of a instruction break, continue, goto or return, or the spread of a exception for out of instruction try.

Within a treated exception, it is guaranteed that the block finally will be executed.

You can use the method Environment.FailFast() to finalize the application immediately, causing the block finally not be executed.

However, skip the block finally and execute the code the way you want it is not possible.

  • Thank you very much! I’m trying to implement in my code, but I’m not getting it. There’s how you give me this support ?

  • @Rodrigooliveira use Environment.FailFast("Um erro fatal ocorreu.");. Remember to put using System; at first

  • I’m implementing, but there’s running Finally. Let’s chat to show you.

  • @Rodrigooliveira placed inside the block catch?

  • Yeah. Take a look. catch (Exception ex)
 {
 Console.WriteLine("Erro ao tentar fazer a conta.");
 Environment.FailFast(causeOfFailure);

  • If you don’t want to run Finally, then why not take the code out of it (which would apparently be some disposition of the resources), and put after the Try...catch. In that case if I didn’t want to continue the application, I would drop her in the catch. By the way, the goto cannot skip the Finally: https://msdn.microsoft.com/en-us/library/aa664758(v=vs.71). aspx

Show 1 more comment

5

The purpose of the block Finally is to be executed both after the execution of the block Try, when after any block catch. There’s no "skip it".

When we start some process in the block Try, that needs to be terminated, such as connection to the database or opening a file, we usually use the block Finally to end the process. Thus, we avoid placing the closure code on the block Try and in all blocks catch.

In the code presented in your question, there is no reason to have a block Finally. So just don’t implement it.

  • I understand your logic. I think I expressed myself wrong. I want to finalize the application within the catch block. Is there any way ?

  • 1

    Environment.Exit(0);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.