Как лучше всего использовать C # try / catch / finally, чтобы вести себя как if / else? - PullRequest
1 голос
/ 29 июля 2011

Я пытаюсь настроить try / catch / finally, чтобы вести себя как if / else.Я не уверен, что самый элегантный способ сделать эту простую вещь.

public bool login()
{
bool isLoggedIn = false;
if (connectToServer(Path,username,password) ) // if successful
  {
     isLoggedIn = true;
  }
  else
  {

  }

return isLoggedIn;
}

Вот то, что я пытался с Исключениями.

public bool login()
{
 bool isLoggedIn = false;

 try{
    connectToServer(Path,username,password)
    isLoggedIn = true; 
  }
  catch(myConnectionException ex)
  {


  }

return isLoggedIn;
}

2-я строка isLoggedIn собираетсявыполнить, хотя предыдущая строка вызывает исключение при неудаче.Я хочу спросить: «если было сгенерировано исключение, я не хочу, чтобы эта строка выполнялась. Могу ли я (должен ли я) получить доступ к объекту исключения в этой точке для тестирования? (Или это выходит за рамки?)бывший программист на C, поэтому я стараюсь "держать это на C #", чтобы сделать простую вещь. Я просто хочу усовершенствовать свои навыки и соответствовать "лучшим практикам". Спасибо DTM

Ответы [ 6 ]

10 голосов
/ 29 июля 2011

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

Я бы рассмотрел объединение двух подходов.

4 голосов
/ 29 июля 2011

Что было бы неправильно делать что-то подобное?

bool isLoggedIn = false;

try
{
    isLoggedIn = connectToServer(Path, username, password);
}
catch (ExceptionType1 ex1)
{
    //Recover from this exception type.
}
catch (ExceptionType2 ex2)
{
    //Recover from this exception type.
}

Исключения не являются "заменой" для операторов if.Они предназначены для обработки состояний ошибок, если таковые возникают, и их использование для контроля потока приложения, безусловно, не рекомендуется.По крайней мере, они медленные, и использование их для управления потоком может скрыть от вас реальные реальные ошибки, когда вы действительно хотите, чтобы приложение не работало.

РЕДАКТИРОВАТЬ: как @Anthony Pegram упоминает в комментарии ниже,Работа со всеми типами исключений в одном блоке перехвата - плохая практика (в этом я слишком часто бываю виновата), поскольку она также скрывает от вас исключения, которые вы, возможно, захотите обработать специально.

0 голосов
/ 29 июля 2011

В этом простом примере

isLoggedIn = true;

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

Как упоминалось ранее: не используйте исключение вместо if / then / else или switch / case.Если в вашем коде больше вызовов методов после установки isLoggedIn в значение true, вам следует сбросить его на false, потому что в перехвате это будет возвращаемый результат.

Кстати, в правиле нет разницыиспользуя исключения в C # или я C + +.Это кажется общим для обоих языков.

0 голосов
/ 29 июля 2011

Это будет работать, но не должно быть сделано. Лучше всего было бы закодировать его как:

public bool login()
{
    return connectToServer(Path,username,password);
}

Коротко и сладко. Исключения очень плохи в использовании, кроме исключительных случаев. Конечно, если вы хотите получить исключения connectToServer, вы можете использовать что-то вроде:

public bool login()
{
    try
    {
        return connectToServer(Path,username,password);
    }
    catch(exception ex)//or the specific exception you are after
    {
        return false;
    }
}

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

0 голосов
/ 29 июля 2011

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

Пусть connectToServer всегда возвращает истину или ложь (внутренне перехватывает ошибки и возвращает ложь). и просто:

return connectToServer(Path,username,password);
0 голосов
/ 29 июля 2011

connectToServer должен выдать myConnectionException, если это не удалось

...