2009-03-02 2 views
10

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

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

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

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

+0

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

+0

Избиты на 20 секунд! В самом деле, что я собираюсь сказать; если есть исключение - ЕСЛИ вы этого не ожидаете и можете сделать что-то полезное, пусть оно пузырится к вызывающему. –

+2

Существенные проблемы с глотанием - вот настоящая проблема. –

ответ

27

Храните возвращаемое значение во временной переменной, как это:

public DataTable ReturnSomething() 
{ 
    DataTable returnValue = null; 

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

    return returnValue; 
} 
+0

простой и выполняет эту работу. – 2009-03-02 16:56:42

+3

Как и другие, вы должны подумать о том, чтобы исключить исключение вместо установки ErrorString. Если вы хотите исключение из своего собственного сообщения, вы должны выбросить новое исключение, причем исходное исключение является внутренним исключением. throw new ArgumentException («Мое сообщение», e); – Svish

+0

Я согласен с Svish и другими; хотя я попытался ответить на ваш вопрос по заданию, я не думаю, что это лучшее решение вашей проблемы. – Simon

14

Вы должны поднять/выбросить исключение в свой блок 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#.

+1

Возможно, вы захотите просто бросить, поскольку throw e изменит стек исключений. –

+0

Хорошо, что у вас здесь. –

+1

Просто отметить; добавление 'throws' в метод - это концепция Java, которая не существует в .NET. – Robula

3

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

+0

Все зависит от обстоятельств. Вы всегда должны задавать вопрос: «Что это значит, если здесь происходит исключение?» а не следовать той же практике. Отчасти причина использования обработчика исключений - это, конечно, HANDLE исключение. – plinth

5

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

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

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

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

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

    // logic here 
    return dt; 
} 
0

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

0

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

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

3

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

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

Как об этом:

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

Не будет ли это ошибкой компилятора, поскольку errorString - это выход, и он не гарантированно установлен? –

+0

yeap, вы правы, я просто пишу это в редакторе SO :) редактирование! – Canavar

+0

@ScarletGarden: Я делаю то же самое;] –

3

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

} 

}

6

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

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

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

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

0

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

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

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