2015-11-23 6 views
3

ReSharper рекомендует реконструировать исключение, а затем, когда я это делаю, он говорит, что все предложение catch в любом случае избыточно и предлагает удалить его.Почему ReSharper рекомендует удалить собственное исправление?

Я использую этот код (от Methodman here):

public static DataTable ExecuteDataSet(string sql, CommandType cmdType, params SqlParameter[] parameters) 
{ 
    using (DataSet ds = new DataSet()) 
    using (SqlConnection connStr = new SqlConnection(UsageRptConstsAndUtils.CPSConnStr)) 
    using (SqlCommand cmd = new SqlCommand(sql, connStr)) 
    { 
     cmd.CommandType = cmdType; 
     foreach (var item in parameters) 
     { 
      cmd.Parameters.Add(item); 
     } 

     try 
     { 
      cmd.Connection.Open(); 
      new SqlDataAdapter(cmd).Fill(ds); 
     } 
     catch (SqlException ex) 
     { 
      throw; 
     } 
     return ds.Tables[0]; 
    } 
} 

Когда я ReSharper Осмотреть> Код проблемы в решении, он задается вопросом, является ли "исключение Rethrow возможно предназначены" здесь:

catch (SqlException ex) 
{ 
    throw ex; 
} 

Если я согласен с предлагаемым исправлением ReSharper («исключение перебора»), Resharper удаляет «ex»:

catch (SqlException ex) 
{ 
    throw; 
} 

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

Но, конечно, если я удалю блок catch, он не будет компилироваться («Ожидаемый улов или, наконец,»). Я мог бы удалить попробовать ... но ... если я могу изменить его к этому:

   catch (SqlException sqlex) 
       { 
        for (int i = 0; i < sqlex.Errors.Count; i++) 
        { 
         var sqlexDetail = String.Format("From 
ExecuteDataSet(), SQL Exception #{0}{1}Source: {2}{1} 
Number: {3}{1}State: {4}{1}Class: {5}{1}Server: {6}{1}Message: {7} 
{1}Procedure: {8}{1}LineNumber: {9}", 
          i + 1, // Users would get the fantods if they 
saw #0 
          Environment.NewLine, 
          sqlex.Errors[i].Source, 
          sqlex.Errors[i].Number, 
          sqlex.Errors[i].State, 
          sqlex.Errors[i].Class, 
          sqlex.Errors[i].Server, 
          sqlex.Errors[i].Message, 
          sqlex.Errors[i].Procedure, 
          sqlex.Errors[i].LineNumber); 
         MessageBox.Show(sqlexDetail); 
        } 
       } 
       catch (Exception ex) 
       { 
        String exDetail 
String.Format(UsageRptConstsAndUtils.ExceptionFormatString, ex.Message, 

Environment.NewLine, ex.Source, ex.StackTrace); 
        MessageBox.Show(exDetail); 
       } 

... осмотр ReSharper в не жалуется на него.

+4

Оригинальные 'throw' и' throw ex' оба бессмысленны. Ваш последний пример (с кодом в блоке 'catch') явно делает что-то с' ex', поэтому я думаю, что Resharper понимает это и не жалуется. – xxbbcc

+1

http://stackoverflow.com/questions/730250/is-there-a-difference-between-throw-and-throw-ex – xxbbcc

+1

Просто 'throw;' (или релиз, как мне нравится называть его) бессмысленно, и 'throw ex;' (который я называю rethrow) на самом деле плохо, потому что он сбрасывает трассировку стека. Таким образом, в основном Resharper сначала фиксирует неверную практику «throw ex», а затем фиксирует бессмысленность просто «броска». – juharr

ответ

6

Когда вы делаете это, вы переустанавливаете стек вызовов, который теряет ценную информацию о том, что именно заставило исключение.

catch (SqlException ex) 
{ 
    throw ex; 
} 

Если ReSharper были быть умнее, он бы сказал вам, чтобы просто удалить ту часть, в первую очередь, вы экономите время, которое потребовалось, чтобы переписать ту часть кода.

Следующий код лучше, так как он не теряет информацию о трассировке стека, но это необязательно.

catch (SqlException ex) 
{ 
    throw; 
} 

Даже если опустить выше, исключение будет «пузыриться» и может быть просто поймали где-то дальше вверх по стеку в вашей программе, где бы вы готовы на самом деле иметь дело с ним (срубы его , или отобразить сообщение, или принять некоторые альтернативные действия и т. д.).

1
catch (SqlException ex) 
{ 
    throw ex; 
} 

Плохая практика программирования. Вы теряете исходную трассировку стека из сброшенного исключения.

catch (SqlException ex) 
{ 
    throw; 
} 

Абсолютно ничего для вас не существует, за исключением случаев, когда повторно выбрасывается одинаковое исключение. Re-sharper ожидает, что вы сделаете что-то с переменной ex, например, в журнале.

Смежные вопросы