Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
A C#-ban a program futásidejű hibáit a program egy kivételeknek nevezett mechanizmussal propagálja. A kivételeket olyan kód okozza, amely hibát tapasztal, és a hibát kijavító kód észleli. A kivételeket a .NET-futtatókörnyezet vagy a program kódja is okozhatja. A kivétel eldobása után a hívásveremben terjed tovább, amíg meg nem talál catch egy, a kivételre vonatkozó utasítást. A nem tapasztalt kivételeket a párbeszédpanelt megjelenítő rendszer által biztosított általános kivételkezelő kezeli.
A kivételeket a forrásból származtatott Exceptionosztályok jelölik. Ez az osztály azonosítja a kivétel típusát, és olyan tulajdonságokat tartalmaz, amelyek részletes információkat tartalmaznak a kivételről. A kivétel kioltásához létre kell hozni egy kivételből származtatott osztály egy példányát, opcionálisan konfigurálni kell a kivétel tulajdonságait, majd a kulcsszó használatával kell eldobni az throw objektumot. Például:
class CustomException : Exception
{
public CustomException(string message)
{
}
}
private static void TestThrow()
{
throw new CustomException("Custom exception in TestThrow()");
}
A kivételt követően a futtatókörnyezet ellenőrzi, hogy az aktuális utasítás egy try blokkon belül van-e. Ha igen, ellenőrzi a rendszer a catch blokkhoz tartozó összes try blokkot, hogy képesek-e észlelni a kivételt.
Catch a blokkok általában kivételtípusokat határoznak meg; ha a catch blokk típusa megegyezik a kivétel típusával, vagy a kivétel alaposztálya, a catch blokk képes kezelni a metódust. Például:
try
{
TestThrow();
}
catch (CustomException ex)
{
System.Console.WriteLine(ex.ToString());
}
Ha a kivételt okozó utasítás nem egy try blokkon belül van, vagy ha az try azt tartalmazó blokk nem rendelkezik egyező catch blokktal, a futtatókörnyezet ellenőrzi a hívási metódust egy try utasítás és catch blokk esetében. A futtatókörnyezet tovább halad felfelé a hívásvermen, és egy kompatibilis catch blokkot keres. A blokk megtalálása és végrehajtása után a catch vezérlő a blokk utáni catch következő utasításnak lesz átadva.
Egy try utasítás több catch blokkot is tartalmazhat. A rendszer végrehajtja a kivételt kezelő első catch utasítást. A rendszer figyelmen kívül hagyja a következő catch utasításokat, még akkor is, ha kompatibilisek. A kivételkezelési blokkok sorrendje a legspecifikusabbtól (vagy a legtöbb származtatottól) a legkevésbé specifikusig. Például:
using System;
using System.IO;
namespace Exceptions
{
public class CatchOrder
{
public static void Main()
{
try
{
using (var sw = new StreamWriter("./test.txt"))
{
sw.WriteLine("Hello");
}
}
// Put the more specific exceptions first.
catch (DirectoryNotFoundException ex)
{
Console.WriteLine(ex);
}
catch (FileNotFoundException ex)
{
Console.WriteLine(ex);
}
// Put the least specific exception last.
catch (IOException ex)
{
Console.WriteLine(ex);
}
Console.WriteLine("Done");
}
}
}
A catch blokk végrehajtása előtt a futtatókörnyezet ellenőrzi finally a blokkokat.
Finally a blokkok lehetővé teszik a programozó számára, hogy eltávolítson minden nem egyértelmű állapotot, amely egy megszakított try blokkból maradhat, vagy hogy külső erőforrásokat (például grafikus fogantyúkat, adatbázis-kapcsolatokat vagy fájlstreameket) szabadítson fel anélkül, hogy megvárná a kukagyűjtőt a futásidőben az objektumok véglegesítéséhez. Például:
static void TestFinally()
{
FileStream? file = null;
//Change the path to something that works on your machine.
FileInfo fileInfo = new System.IO.FileInfo("./file.txt");
try
{
file = fileInfo.OpenWrite();
file.WriteByte(0xF);
}
finally
{
// Closing the file allows you to reopen it immediately - otherwise IOException is thrown.
file?.Close();
}
try
{
file = fileInfo.OpenWrite();
Console.WriteLine("OpenWrite() succeeded");
}
catch (IOException)
{
Console.WriteLine("OpenWrite() failed");
}
}
Ha WriteByte() kivételt dobott, a második try blokkban lévő kód, amely megpróbálja újra megnyitni a fájlt, sikertelen lesz, ha file.Close() nincs meghívva, és a fájl zárolva marad. Mivel finally a blokkok akkor is végrehajtásra kerülnek, ha kivételt okoznak, az finally előző példában szereplő blokk lehetővé teszi a fájl helyes bezárását, és segít elkerülni a hibát.
Ha nem található kompatibilis catch blokk a hívásveremen egy kivétel kiírása után, a következő három dolog egyike következik be:
- Ha a kivétel egy véglegesítőben van, a véglegesítő félbeszakad, és az alap véglegesítő, ha van ilyen, meghívásra kerül.
- Ha a hívásverem statikus konstruktort vagy statikus mező inicializálót tartalmaz, akkor egy TypeInitializationException kivétel kerül kiváltásra, amelynek InnerException tulajdonságához az eredeti kivétel van rendelve.
- Ha eléri a szál kezdetét, a szál leáll.