Jak poprawnie używać try, catchów

0

Witam, jak poprawnie używać try catchów?
Zastanawiam się kiedy blok kodu otaczać try'em? Przecież tak naprawdę każda instrukcja może wyrzucić wyjątek? Choćby wyjście poza zakres tablicy. W takim wypadku można powiedzieć że cały program powinien być try'u. Może należy brać takie instrukcje które wyrzucają wyjątek nie z błędu programisty? Jak otwarcie FileStream (gdyż plik może nie istnieć), czy połączenie z bazą danych
(brak internetu). Prosiłbym o wytłumaczenie tego zagadnienia.

1

Ja bym zmienił patrzenie, nie "kiedy używać try", a "kiedy łapać catch". Zmiana czysto słowna, ale ważna

Łapać tam, gdzie jest z tego jakiś sens, gdzie da się coś mądrego z tym zrobić.
Inaczej mówiąc, w wielu miejscach nawet jak złapiemy wyjątek, niewiele z tym problemem zrobimy. Np funkcji obliczającej na tablicy przykładowe wyjście poza. Funkcja i tam musi wykonać return. Ale w punkcie wywołania BYĆ MOŻE tak.
Albo otwarcie połączenia do bazy w programie GUI. Samo w sobie jest nieudane, ale łapiąc w dobrym miejscu możemy usera poprosić o poprawienie parametrów.

1

Pojedyncze instrukcje owijasz w try catch tam, gdzie spodziewasz się konkretnego błędu, który chcesz i możesz obsłużyć w konkretny sposób, np. błąd połączenia z bazą danych -> retry za 5 sekund, int.Parse nie przeszedł -> wyświetl błąd walidacji.
Dodatkowo możesz owinąć cały program żeby obsłużyć te błędy których nie przewidziałeś i np. zalogować błąd, wysłać telemetrię i wyświetlić komunikat "nieznany błąd, spróbuj ponownie".

0
int main()
{
     string UserName;
     try
     {
          UserName.ToString(); // Powstanie wyjątek. Dostaniesz NullreferenceException. Zamiast program się wyłączyć przekaże ten wyjątek do Catch()
     }
     catch(Exception e)
     {
          Console.WriteLine("Nie wykonasz operacji na UserName bo jest równy NULL");
     }
}
1

Po pierwsze. Nie każda instrukcja musi wyrzucić wyjątek.
Po drugie. Przed błędami można się bronić w różny sposób.Można np. sprawdzić poprawność wprowadzanych danych.
Instrukcji try catch używa się w ostateczności dlatego że to jest dodatkowe niepotrzebne obciążenie dla procesora.

Napisałeś jeszcze że najlepiej byłoby cały program ująć w instrukcję try.
Nie chodzi tylko o to, żeby przechwycić każdy błąd ale żeby wiedzieć jaki to jest błąd i odpowiednio obsłużyć dany błąd.

Radziłbym przeczytać chociaż jedną dobrą książkę o C#

1

Nawiązując do poprzedniego posta źle zrozumiałem pytanie. Myślałem, że pytasz się w jaki sposób używać try catch, a nie w jakich przypadkach.
Najprościej mówiąc try catch używa się wtedy, kiedy nie możesz wykryć błędu. W przykładzie pierwszym niewskazane jest używanie try catch, ponieważ możemy obsłużyć błędnie wpisane dane:

bool Connect(string str)
    {
        if(string.IsNullOrEmpty(str))
            return false;
        return true;
    }
if(Connect(null))
        {
              // wykonało się
        }
        else
        {
             // błąd
        }

W następnej metodzie nie możemy obsłużyć błędu i mamy dwa wyjścia:

void Connect(string str)
    {
        if(string.IsNullOrEmpty(str))
            throw new ArgumentNullException();
    }

Wyjście 1: obsługa błędu przed wywołaniem

if (string.IsNullOrEmpty(str))
        { }// obsługa błędu
        else
            Connect(str)

Wyjście 2: try catch

try
        {
            Connect(str);
        }
        catch(Exception e)
        {

        }

Według mnie prawda jest taka, że chyba wszystko da się zrobić bez użycia try catch. Wystarczy mieć wiedzę na temat używanych metod, kontrolować wprowadzane dane zanim się ich użyje. Jednak - szczególnie w komunikacji sieciowej - przeszkód w połączeniu może być masa i te błędy nie muszą leżeć po naszej stronie. Wtedy warto użyć try catch aby pozbyć się nawet takiego problemu jak zanik internetu podczas pobierania danych z bazy danych (bo przecież można było wcześniej sprawdzić czy jest).

Wybór czy użyć czy nie leży po strony programisty. Musi on sam ocenić czy bez tego jego aplikacja będzie niezawodna

0

Nie wiem czy wszystko się da zrobić bez użycia try catch, widziałem Apki korzystające z bibliotek trzecich które czasem sypnął wyjątkiem nie wiedzieć z czego i po co - bo coś się tam zmieniło.
Wyjątki są OK, lepiej nastawić się gdzieś catchem blisko wyjątku na poziomie kodu bo gdzieś tam na górze jest jakiś globalny catch ale może być różnie z diagnostyką problemu.
Drugi aspekt to co zrobić z wyjątkiem i z użytkownikiem.
Poprawcie mnie jeśli się mylę, ale aplikacja desktopowa jak nie przechwyci wyjątku to się zatrzyma z brzydkim stack tracem, aplikacja webowa typu Asp.Net pewnie przechwyci wyjątek na poziomie strony, lub aplikacji i wyświetli 404 ErrorPage.
Co ma zrobić z tym użytkownik?
Jak się da - to wyświetlić mu co należy poprawić, jeśli nie, a nie jest to krytyczna funkcjonalność to LOG Exception i puścić program dalej z jakimś WARN, a jeśli jest to krytyczna funkcjonalność to LOG + komunikat że się nie da ERROR + jakiś email do supportu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0