Блоки try-catch с типом возврата

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

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

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

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

Ответ 1

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

public DataTable ReturnSomething()
{
    DataTable returnValue = null;

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

    return returnValue;
}

Ответ 2

Вы должны поднять/выбросить исключение в свой блок 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: Извините за любую синтаксическую ошибку, я немного ржавый на С#.

Ответ 3

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

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

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

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

Ответ 4

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

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

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

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

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

    // logic here
    return dt;
}

Ответ 5

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

Ответ 6

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

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

Ответ 7

Если вы собираетесь возглавить "не выбрасывать маршрут исключения" (который я не обязательно рекомендую), вы можете следовать методу 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;

}

}

Ответ 8

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

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;
}

Ответ 9

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

Ответ 10

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

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

Ответ 11

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

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;
      }

}