Попробуй наконец загадку

Рассматривать,

        static void Main(string[] args)
        {
            Console.WriteLine(fun());
        }

        static int fun()
        {
            int i = 0;
            try
            {
                i = 1;
                return i;
            }
            catch (Exception ex)
            {
                i = 2;
                return i;
            }
            finally
            {
                i = 3;
            }
        }

Пример кода выводит "1". но значение i меняется на 3 в блоке finally. Почему значение "i" не изменилось на 3?

Спасибо,

5 ответов

Решение

Рассмотрим этот код - я думаю, что код объясняет, что вы думаете, и как вы можете сделать то, что, по вашему мнению, должно произойти:

static void Main(string[] args)
{
    int counter = 0;
    Console.WriteLine(fun(ref counter)); // Prints 1
    Console.WriteLine(counter); // Prints 3
}        

static int fun(ref int counter)
{
  try
  {
      counter = 1;
      return counter;
  }
  finally
  {
      counter = 3;
  }
}

С помощью этого кода вы возвращаете 1 из метода, но вы также устанавливаете переменную counter равной 3, к которой вы можете получить доступ извне метода.

Вы должны помнить, что, наконец, выполняется после всего остального в попытке и поймать. Поместите оператор return после оператора try/catch/finally, чтобы он вернулся 3.

Я полагаю, если вы используете ссылочный тип вместо типа значения, вы получите другое поведение.

Когда вы говорите "return i"... C# помещает это возвращаемое значение во временную область хранения (память), а затем запускает ваш код "finally"... если блок finally мог изменить это значение, это нарушило бы безопасность. финализм блока finally.

Это как оператор использования с возвратом внутри... "Утилизация" все еще будет происходить ПОСЛЕ возврата (так сказать).

Наконец всегда выполняется

Ваш код всегда выполняется окончательно, независимо от того, было ли выброшено исключение или нет. Итак, ваш код должен быть:

try
{
    i = 1;
}
catch
{
    i = 2;
}
finally
{
    i = 3;
}
return i;

Но в этом тривиальном случае, наконец, блок не будет иметь особого смысла. Потому что мы всегда вернем 3 независимо от того, что случилось до этого.

Наконец используется для освобождения ресурсов

finally Блок обычно должен использоваться, когда вы должны освободить некоторые системные ресурсы, выделенные в try блок (т. е. открытие соединения с БД для чтения данных в try заблокировать и закрыть его в finally). Таким образом, они всегда будут освобождены независимо от того, было ли исключение или нет. В этом случае нет смысла использовать finally блок.

Другие вопросы по тегам