попробуйте перехватить блоки с возвращаемым типом
-
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;
}
}