попробуйте перехватить блоки с возвращаемым типом

StackOverflow https://stackoverflow.com/questions/602699

  •  03-07-2019
  •  | 
  •  

Вопрос

Если у меня есть метод, который возвращает что-то, например

public DataTable ReturnSomething()
{
   try
   {  
      //logic here
     return ds.Tables[0];
   }
   catch (Exception e)
   {
      ErrorString=e.Message;
   }
}

Это приводит к ошибке компилятора, очевидно, потому, что catch{} блок ничего не возвращает.

Поэтому, когда у меня есть методы с возвращаемыми значениями, я не использую блок try-catch, что является плохой практикой.Если есть ошибка, я хотел бы присвоить этой ошибке значение error string.Но тогда мне также нужно возвращаемое значение.Совет?

Это было полезно?

Решение

Сохраните возвращаемое значение во временной переменной, подобной этой:

public DataTable ReturnSomething()
{
    DataTable returnValue = null;

    try
    {
        //logic here
        returnValue = ds.Tables[0]; 
    }
    catch (Exception e)
    {
        ErrorString=e.Message;
    }

    return returnValue;
}

Другие советы

Вы должны вызвать / сгенерировать исключение в вашем блоке catch и обработать его в вызывающем методе.

public void invokeFaultyCode()
{
    try
    {
        DataTable dt = ReturnSomething();
    }
    catch(Exception e)
    {
        // Print the error message, cleanup, whatever
    }    
}
public DataTable ReturnSomething() throws Exception
{
   try
   {  
      //logic here
     return ds.Tables[0];
   }
   catch (Exception e)
   {
      ErrorString=e.Message;
      throw;
   }
}

PS:Извините за синтаксическую ошибку, я немного подзабыл C #.

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

Лично я считаю, что использовать try catch в этой процедуре излишне, поскольку у вас должен быть вызывающий объект, обрабатывающий исключение.

В моем примере это было бы закодировано следующим образом...

private void DoSomething() {
    try {
        DataTable dt = ReturnSomething();
    }
    catch (Exception ex) {
    }    
}

public DataTable ReturnSomething() {
    DataTable dt = new DataTable();

    // logic here
    return dt;
}

Переменная errorString подозрительно похожа на переменную с кодом ошибки.Рекомендуемая практика заключается в использовании исключений для передачи информации об ошибках напрямую, где это необходимо, вместо того, чтобы сохранять информацию в кодах ошибок.

Вы фактически делаете то же самое со своей errorString, что и вы, если бы вы просто позволили исключению быть перехваченным вызывающей стороной:снятие ответственности за реагирование на ошибку с самого метода.Это хорошая цель, которую нужно иметь.Но использование строки ошибки ничего не дает вам по сравнению с использованием исключения.На самом деле, таким образом, вы теряете информацию.Существует множество типов ошибок, которые могут возникнуть, и со многими из них связаны особые исключения со своими собственными особыми свойствами для хранения контекстной информации о сбое.Просто сохраняя сообщение в виде строки, вы теряете эту информацию.

Таким образом, если вашей целью не является специально скрыть тип ошибки, возникающей у вызывающего объекта, вы можете выиграть, только пропустив исключение.

Еще одна вещь, которую следует учитывать, - это действительно ли это сценарий ошибки.Если это так, то очень маловероятно, что ваш вызывающий метод вообще будет заботиться о том, какое возвращаемое значение.В этом случае вам не о чем беспокоиться, просто отпустите исключение и ничего не возвращайте.Если на самом деле это НЕ сценарий ошибки, и вызывающий абонент просто собирается продолжить и сделать что-то еще, что ж, это решать вызывающему абоненту, не так ли?По-прежнему нет особой пользы от возврата строки ошибки и фиктивного значения DataTable или null, по сравнению с выдачей исключения со всей его контекстной информацией о сбое.

Если вы собираетесь выбрать "не создавать маршрут исключения" (который я не обязательно рекомендую), вы могли бы следовать подходу TryParse, используемому MS.

Что -то вроде:

private string FillDataTable(out DataTable results)
{

  try
{
  results = new DataTable(); //something like this;
  return String.Empty;
}
catch (Exception ex)
{
  results = null;
 return ex.Message;

}

}

Это зависит от вашего приложения.Ты можешь вернуться null, пустой DataTable или все, что подходит в данных обстоятельствах.

я бы предположил, что вы все еще можете установить сообщение, а затем вернуть null или любой другой эквивалент c #

public DataTable ReturnSomething(){ 
   try {
        //logic here 
        return ds.Tables[0]; 
   } catch (Exception e) {
        ErrorString=e.Message;
        return null;
   }
}

Как насчет этого :

public DataTable ReturnSomething(out string errorString)
{
   errorString = string.Empty;
   DataTable dt = new DataTable();
   try
   {  
      //logic here
     dt = ds.Tables[0];
   }
   catch (Exception e)
   {
      errorString = e.Message;
   }
   return dt;
}

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

Если вам нужно перехватить исключение там и что-то сделать, все в порядке, но если это все еще случай ошибки, вы также должны создать его или другое исключение, возможно, с тем, которое вы только что поймали как InnerException .

Я думаю, что ваш код выполняется на достаточно высоком уровне стека вызовов и он сочетается с кодом пользовательского интерфейса.Если это действительно так, вы могли бы return null в блоке catch.Однако, если вы пишете повторно используемый код, вам следует реорганизовать его так, чтобы он не содержал манипуляций с пользовательским интерфейсом и обрабатывал исключение на более высоком уровне в стеке вызовов.

Вы можете сделать это, как показано в примере кода ниже.

public DataTable ReturnSomething(out string OutputDesc)
{
   try
      {
         //logic here
         OutputDesc = string.Format("Your Successful Message Here...");
         return ds.Tables[0];
      }
      catch (Exception e)
      {
         OutputDesc =e.Message;
         return null;
      }

}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top