2015-03-12 4 views
0

поэтому в настоящее время я пишу программу что-то вроде этого:как управлять программой для обработки исключительных ситуаций

try 
{ 
    mainprocessing(); 
} 
catch (exception e) 
{ 
    //first catch block. 
    //do something here 
} 

mainprocessing() 
{ 
    try 
    { 
     string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1"); //I am calling ReadCellValue() method to check the value of A1 cell of an excel spreadsheet and if it is null, it will be handled in the following catch block. 
    } 
    catch (NullReferenceException e) 
    { 
     //second catch block 
     //something here to handle it 
    } 
} 

Но когда я запускаю программу сейчас, если string value равно нулю, то исключение будет обрабатываться в first catch block , Однако я хочу, чтобы это было обработано в second catch block. Есть ли способ манипулировать этим?

+2

Вы действительно не должны использовать исключение для управления потоком. Проверьте значение вместо этого. – VMAtm

+0

Вам нужно также поймать 'NullReferenceException' в« second »try/catch –

+0

@RussCam извините, что я новичок в C#, я изменил его на' NullReferenceException', теперь это правильно? – OPK

ответ

0

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

Когда значение равно null и пытается получить доступ к этой переменной, ссылка на фактический объект не будет отображаться, поэтому будет выведено исключение NullReferenceException, но в этом случае вы назначаете значение ссылке, чтобы было другое исключение, чем исключение NullReferenceException.

Единственный способ узнать, какое исключение выбрано, добавить еще один блок catch ниже исключения NullReferenceException.

catch (NullReferenceException e) 
{ 
    //second catch block 
    //something here to handle it, LOG IT! 
} 
catch (Exception exception) 
{ 
    Type exceptionType = exception.GetType(); 
} 

Когда исключение было обработано (поймают) по программе возвращается в точку, где эта функция вызывается, в этом случае 'mainprocessing.

Если вы явно хотите, чтобы попасть в блок обработки наиболее верхнего уровня исключений, просто бросить новый Exception в улове, как это:

mainprocessing() 
{ 
    try 
    { 
     string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1"); //I am calling ReadCellValue() method to check the value of A1 cell of an excel spreadsheet and if it is null, it will be handled in the following catch block. 
    } 
    catch (NullReferenceException e) 
    { 
     //second catch block 
     //something here to handle it, LOG IT! 
     throw new Exception("top level exception"); 
    } 
} 
+0

Это должно быть «throw new Exception» («исключение верхнего уровня», e); ', это плохая практика и, как правило, неправильная привычка потерять исходное исключение. – bokibeg

+0

Это абсолютно правильно! И да, это отличный пример того, как подойти к этому по-другому. – Kevin

0

Как уже упоминалось в комментариях обработки исключений не способ управление потоком рукоятки в C#. Вы используете их, если что-то неожиданное произойдет, что вы не можете проверить заранее, перед запуском вашего процесса (например, файл поврежден, и ваше чтение неожиданно прервано).

В вашем случае просто пойти с простой if проверки:

string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1"); 

if (string.IsNullOrWhiteSpace(value)) 
{ 
    // Handle the null/empty string here. 
    // From what you said probably the logic you wanted to use in your second catch block. 
} 

EDIT:

Для обработки исключения на уровне ReadCell просто проверить, если это нуль перед обращением к значению. Тогда у вас есть пара вариантов. Вы можете прервать выполнение (return) или попытаться получить экземпляр ReadCell.

if (ReadCell == null) 
{ 
    // abort the execution, create 
} 

string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1"); 

В качестве альтернативы просто отступ несколько if s:

if (ReadCell != null) 
{ 
    string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1"); 

    if (string.IsNullOrWhiteSpace(value)) 
    { 
     // Handle the null/empty string here. 
     // From what you said probably the logic you wanted to use in your second catch block. 
    } 
} 
else 
{ 
    // Handle null case for ReadCell. 
} 
+0

Проблема заключается в том, что 'ReadCell.ReadCellValue()' находится в классе 'ReadCell', и если я использую' if (string.IsNullOrWhiteSpace (значение)) ', исключение« nullreference »не будет обрабатываться, поэтому программа будет распространять исключение к внешнему блоку 'catch' – OPK

+0

Я отредактировал свой ответ, чтобы настроить его на случай чтения ReadCell – PiotrWolkowski

0

Вот как вы должны обрабатывать исключения в вашем конкретном случае:

private void btnDataStuff_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      ProcessSomeData(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error: " + ex.Message); 
      MessageBox.Show("Inner exception: " + ex.InnerException.Message); 
     } 
    } 

    private void ProcessSomeData() 
    { 
     try 
     { 
      // Code where NullReferenceException exception happens 
     } 
     catch (NullReferenceException ex) 
     { 
      throw new ApplicationException("Data is null!!!", ex); 
     } 
    } 

Это правильный способ справиться и распространять свои исключения , Я думаю, это то, чего вы изначально хотели достичь. Если NullReferenceException исключение происходит в методе ProcessSomeData - он будет распространяться как новое исключение с Data is null!!! сообщение но он также будет держать оригинальное исключение, поскольку он хранит важную информацию для последующего отладки (стек вызовов между прочим).Таким образом, вы можете иметь «приятные» сообщения об ошибках в своем приложении для конечного пользователя и оригинальные исключения для отладки программиста при необходимости.

Это очень простой пример. Пожалуйста, прочитайте this to learn best practices when handling exceptions. Это один из самых важных аспектов программирования, который вам нужно будет узнать - вы будет eventuall изучите его в любом случае, но зачем идти по жесткому пути, когда вы можете сделать вашу жизнь проще с самого начала.

Также читайте на C# coding conventions, чтобы вы могли написать качественный код с самого начала.

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

+1

, также вы можете реализовать свой собственный тип исключения и не использовать класс' Exception', только 'ApplicationException' – VMAtm

+0

You ' Очень верно, я отредактировал ответ, чтобы включить 'ApplicationException'. Спасибо за подсказку! – bokibeg

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