Это хороший подход для вызова return внутри с помощью оператора {}?


Я просто хочу знать, это безопасный / хороший подход к вызову return внутри using блок.

например.

using(var scope = new TransactionScope())
{
  // my core logic
  return true; // if condition met else
  return false;
  scope.Complete();
}

мы знаем, что в последний раз самая кудрявая скобка dispose() будет отменена. Но что будет в приведенном выше случае, так как return выводит элемент управления из заданной области (AFAIK)...

  1. мой scope.Complete() вам звонил?
  2. и так для области dispose() метод.
7 71

7 ответов:

это совершенно безопасно позвонить return внутри using блок, так как блок using-это просто try/finally заблокировать.

в вашем примере выше после возвращения true, область будет удалена и значение возвращается. return false и scope.Complete() будет не вам звонил. Dispose однако будет вызван независимо, так как он находится внутри блока finally.

ваш код по существу такой же, как этот (если это облегчает поймите):

var scope = new TransactionScope())
try
{
  // my core logic
  return true; // if condition met else
  return false;
  scope.Complete();
}
finally
{
  if( scope != null) 
    ((IDisposable)scope).Dispose();
}

пожалуйста, имейте в виду, что ваша сделка будет никогда commit, поскольку нет никакого способа добраться до scope.Complete() для совершения сделки.

это нормально - finally предложения (это то, что закрывающая фигурная скобка using предложение делает под капотом) всегда выполняется, когда область остается, независимо от того, как.

однако это верно только для операторов, которые находятся в блоке finally (который не может быть явно установлен при использовании using). Поэтому в вашем примере scope.Complete() никогда не будет вызван (я ожидаю, что компилятор предупредит вас о недостижимом коде).

В общем, это хороший подход. Но в вашем случае, если вы вернетесь перед вызовом scope.Complete(), Это будет просто мусор TransactionScope. Зависит от вашего дизайна.

таким образом, в этом примере Complete() не вызывается, а scope удаляется, предполагая, что он наследует интерфейс IDisposable.

объем.Полный обязательно должен быть вызван до return. Компилятор выдаст предупреждение и этот код никогда не будет вызван.

о return сам - да, это безопасно вызывать его внутри using заявление. Использование переводится на try-finally блок За сценой и, наконец, блок должен быть обязательно выполнен.

в приведенном примере есть проблема;scope.Complete() никогда не вызывается. Во-вторых, это не очень хорошая практика, чтобы использовать return инструкция using заявления. Обратитесь к следующей:

using(var scope = new TransactionScope())
{
    //have some logic here
    return scope;      
}

в этом простом примере, суть в том, что, значение scope будет null, когда использование оператора будет завершено.

поэтому лучше не возвращаться внутрь с помощью операторов.

чтобы убедиться, что scope.Complete() будет вызван, оберните его с try/finally. Элемент dispose называется потому, что у вас есть обернуть его с using это альтернатива try/finally блок.

using(var scope = new TransactionScope())
{
  try
  {
  // my core logic
  return true; // if condition met else
  return false;
  }
  finally
  {
   scope.Complete();
  }
}

в этом примере область.Полный() никогда не будет выполняться. Однако команда return очистит все, что назначено в стеке. GC будет заботиться обо всем, что не имеет отношения. Таким образом, если нет объекта, который не может быть поднят GC, нет никаких проблем.