нормально ли иметь try / catch в finally?

#c#

#c#

Вопрос:

это «ок» код?

         try
        { /*stuff*/ }
        catch (Exception e)
        { /*stuff*/ }
        finally
        {
            try
            { /*stuff*/ }
            catch { /*empty*/ }
        }
 

Мне нужно выполнить сложную операцию в finally, и это может привести к сбою, поскольку оно подключается к базе данных a

это выглядит странно для меня, так что. это правильный путь?

Комментарии:

1. Можно ли принимать таблетки, если у вас есть заболевание? Давайте заполним пробелы здесь. В концепции try / catch внутри finally нет ничего плохого, но в зависимости от того, что вы пытаетесь сделать, и каковы ваши конечные цели, могут быть ошибки.

2. не могли бы вы кратко рассказать нам, что вы собираетесь делать в finally?

3. Зависит от того, что такое исключение и как вы собираетесь его обрабатывать. Как минимум, я бы абстрагировал тело finally до одной строки.

4. Для меня это похоже на запах кода… Возможно, код в вашем finally блоке принадлежит другой функции.

5. В одном предложении — Yikes yowsers и sheesh!

Ответ №1:

Это действительно будет зависеть от того, что вы делаете, но лично, если это действительно после другого try catch и сделано после операции, я бы не стал вкладывать его в finally, просто рассматривайте его как еще один try catch . Это устранило бы некоторые «странности» в нем.

Комментарии:

1. это заставляет меня еще раз взглянуть на всю картину (код), и на самом деле ваше право, в моем случае лучше удалить finally и добавить еще одну попытку / catch после исходной.

Ответ №2:

Вложенные блоки try / catch не идеальны, но в некоторых случаях это необходимо. Просто убедитесь, что все ошибки обрабатываются правильно.

Ответ №3:

Идоматически, вы бы сделали это:

 try
{
    /* stuff */
}
catch 
{
    /* stuff */
}
finally 
{
    DoStuff();
}


void DoStuff()
{
    try 
    {
        /* stuff */
    }
    catch
    {
        /* stuff */
    }
}
 

Комментарии:

1. Это не имеет смысла, я не понимаю, как это решает проблему, и вряд ли это идеальная ситуация. Я бы сказал, что оба оператора try catch должны быть в их собственном методе, вызываемом внутри метода, один за другим. Эти методы должны возвращать значение.

Ответ №4:

ДА. Исключение в finally будет скрывать исходное исключение. Это похоже на рекомендацию not to use using in WCF while creating proxies , хотя само по себе это другое обсуждение.

Это приведет к выводу B, а не A:

 static void Main(string[] args)
    {
        try
        {
            try
            {
                throw new ApplicationException("A");
            }
            finally
            {
                throw new ApplicationException("B");
            }
        }
        catch (Exception e)
        {

            Console.WriteLine(e.Message);
        }
        Console.Read();
    }
 

Ответ №5:

ДА. Обычно создание исключения, когда активно другое исключение, приведет к замене первого исключения вторым (более поздним) исключением.

Вот некоторый код, который иллюстрирует, что происходит:

     public static void Main(string[] args)
    {
        try
        {
            try
            {
                throw new Exception("first exception");
            }
            finally
            {
                //try
                {
                    throw new Exception("second exception");
                }
                //catch (Exception)
                {
                    //throw;
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }
 
  • Запустите код, и вы увидите «второе исключение»
  • Раскомментируйте операторы try и catch, и вы увидите «первое исключение»
  • Также раскомментируйте оператор throw;, и вы снова увидите «второе исключение».