Блоки 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;
}
}