Programmering

Beste fremgangsmåter for håndtering av unntak i C #

Unntakshåndtering er teknikken for å håndtere kjøretidsfeil i applikasjonskoden. I utgangspunktet har du to kategorier unntak: Unntak som genereres av applikasjonen og de som genereres av kjøretiden. Unntak bør håndteres med forsiktighet - du bør ha en god ide om hvordan unntak skal håndteres og når de er nødvendige for å bli behandlet i koden din. I dette innlegget vil jeg presentere noen tips og beste praksis for å jobbe med unntak i C #.

Baseklassen for alle unntak i .NET er Unntak. Alle unntaksklasser i unntakshierarkiet kommer direkte eller indirekte fra denne klassen. Klassene ApplicationException og SystemException er hentet fra Exception-klassen. Common Language Runtime (CLR) kaster en forekomst av en type som er avledet fra SystemException når en feil oppstår ved kjøretid. Merk at du aldri skal fange SystemException eller kaste en forekomst av SystemException i programmets kode.

Når du oppretter egendefinerte unntaksklasser, må du alltid komme fra klassen Unntak og ikke fra klassen ApplicationException. En av grunnene til dette er at en forekomst av ApplicationException blir kastet av applikasjonen og aldri av kjøretiden. Når du kaster en forekomst av ApplicationException i koden din, vil du bare øke samtalestakken uten å legge til mye verdi.

Det er en dårlig designtilnærming å bruke unntakshåndtering for å returnere informasjon fra en metode. Hvis du returnerer unntaksdata fra metoden din, er klassesignet ditt feil og bør revurderes. Merk at unntak bobles opp til høyere nivå i metoden anropshierarki, og det er ikke god praksis å håndtere unntak i alle lagene i applikasjonen. Du bør håndtere et unntak så høyt oppe i samtalehierarkiet som mulig - du kan konsumere et unntak i presentasjonslaget og vise passende meldinger til brukeren for å varsle den nøyaktige feilen som har oppstått.

Å kaste et unntak på nytt er nødvendig når du ønsker å tilbakestille en databasetransaksjon. Det er en god praksis å bruke spesifikke unntak som FileNotFoundException, IOException, etc. når du skriver unntakshåndterere og deretter en generell fangstblokk til slutt med Exception-klassen. Dette vil sikre at du blir kjent med den eksakte feilen eller den spesifikke feilen som har oppstått. MSDN uttaler: "ApplicationException-klassen gir ikke informasjon om årsaken til unntak. I de fleste scenarier bør ikke tilfeller av denne klassen kastes. I tilfeller der denne klassen er instantiert, bør en menneskelig lesbar melding som beskriver feilen være overført til konstruktøren. "

Du bør bruke prøvefangstblokker for å håndtere unntak og bruke en endelig blokk for å rydde opp i ressursene som brukes i programmet. Prøveblokken vil inneholde kode som kan heve et unntak, fangstblokken vil bli brukt til å håndtere unntaket kastet i prøveblokken, og den endelige blokken vil bli brukt til å distribuere ressurser programmet har brukt. Merk at den endelige blokken garantert vil bli utført uansett om det har oppstått et unntak eller ikke. Derfor er endelig blokk det beste stedet i koden din for å rydde opp i ressursene programmet ditt har brukt.

Kodebiten nedenfor viser hvordan "bruk" -uttalelsen kan brukes til å disponere ressurser. Merk at "bruk" -uttalelsen tilsvarer prøve - til slutt blokk.

offentlig streng Les (streng filnavn)

{

prøve

{

streng data;

bruker (StreamReader streamReader = ny StreamReader (filnavn))

{

data = streamReader.ReadToEnd ();

}

returnere data;

}

fangst (unntak)

{

kaste;

}

}

Å kaste unntak er dyrt. Det er en dårlig praksis å omlegge unntak - ved omkasting av unntak vil du miste stabelsporet.

prøve

{

// Noe kode som kan gi unntak

}

fangst (Unntak eks)

{

kaste eks;

}

I stedet er det bare å bruke setningen "kaste" hvis du ikke ønsker å håndtere unntaket i unntaksbehandleren og forplante unntaket oppover i samtalehierarkiet.

prøve

{

// Noe kode som kan gi unntak

}

fangst (Unntak eks)

{

kaste;

}

Svelg aldri unntak - du bør aldri skjule feilen som har oppstått. Det er en god praksis å logge unntak i søknaden din. Når du logger unntak, bør du alltid logge unntaksforekomsten slik at hele stabelsporet er logget og ikke bare unntaksmeldingen. Her er et eksempel som illustrerer dette.

prøve

{

// Noe kode som kan gi unntak

}

fangst (Unntak eks)

{

LogManager.Log (ex.ToString ());

}

Du bør aldri bruke unntak for å formidle eller utføre forretningsregler i søknaden din. Du kan unngå unntak i koden din ved å bruke riktig valideringslogikk. Unntak bør i de fleste tilfeller unngås - du bør bare bruke det når det er nødvendig.

Du kan referere til denne MSDN-artikkelen for mer informasjon.