Kivételek létrehozása és kizárása
A kivételek azt jelzik, hogy hiba történt a program futtatása során. A rendszer létrehoz egy hibát leíró kivételobjektumokat, majd az utasítással vagy kifejezéssel együtt dobja el azokatthrow
. A futtatókörnyezet ezután megkeresi a legkompatibilisebb kivételkezelőt.
A programozóknak kivételeket kell kivenniük, ha az alábbi feltételek közül legalább egy teljesül:
A metódus nem tudja befejezni a definiált funkcióit. Ha például egy metódus paraméterének értéke érvénytelen:
static void CopyObject(SampleClass original) { _ = original ?? throw new ArgumentException("Parameter cannot be null", nameof(original)); }
Az objektum állapota alapján nem megfelelő hívás történik egy objektumra. Ilyen lehet például egy írásvédett fájlba való írás. Olyan esetekben, amikor egy objektumállapot nem engedélyezi a műveletet, az osztály származtatása InvalidOperationException alapján dobjon ki egy példányt vagy objektumot. Az alábbi kód egy objektumot dobó InvalidOperationException metódusra mutat be példát:
public class ProgramLog { FileStream logFile = null!; public void OpenLog(FileInfo fileName, FileMode mode) { } public void WriteLog() { if (!logFile.CanWrite) { throw new InvalidOperationException("Logfile cannot be read-only"); } // Else write data to the log and return. } }
Ha egy metódus argumentuma kivételt okoz. Ebben az esetben az eredeti kivételt le kell kapni, és létre kell hozni egy példányt ArgumentException . Az eredeti kivételt a paraméter konstruktorának ArgumentExceptionInnerException kell átadni:
static int GetValueFromArray(int[] array, int index) { try { return array[index]; } catch (IndexOutOfRangeException e) { throw new ArgumentOutOfRangeException( "Parameter index is out of range.", e); } }
Feljegyzés
Az előző példa bemutatja, hogyan használhatja a tulajdonságot
InnerException
. Szándékosan leegyszerűsítik. A gyakorlatban a használat előtt ellenőriznie kell, hogy egy index tartományon belül van-e. Ezt a technikát akkor használhatja kivétel körbefuttatására, ha egy paraméter egy tagja olyan kivételt ad ki, amely nem várható a tag meghívása előtt.
A kivételek egy .StackTrace Ez a sztring tartalmazza az aktuális hívásverem metódusainak nevét, valamint azt a fájlnevet és sorszámot, ahol a kivételt az egyes metódusok kivétele eredményezte. A rendszer automatikusan létrehoz egy StackTrace objektumot a közös nyelvi futtatókörnyezet (CLR) által az throw
utasítás pontjáról, így a kivételeket attól a ponttól kell elvetni, ahol a veremkövetésnek el kell kezdődnie.
Minden kivétel tartalmaz egy .Message Ezt a sztringet úgy kell beállítani, hogy elmagyarázza a kivétel okát. A biztonságra érzékeny információkat nem szabad az üzenet szövegébe helyezni. MessageEmellett tartalmaz egy nevű ParamName tulajdonságot is, ArgumentException amelyet a kivételt okozó argumentum nevére kell beállítani. A tulajdonságválasztóban ParamName a következő értékre kell állítani: value
.
A nyilvános és védett metódusok kivételeket vetnek fel, ha nem tudják elvégezni a kívánt függvényeiket. A kidobott kivételosztály a rendelkezésre álló legspecifikusabb kivétel, amely megfelel a hibafeltételeknek. Ezeket a kivételeket az osztályfunkció részeként kell dokumentálni, és az eredeti osztály származtatott osztályainak vagy frissítéseinek ugyanazt a viselkedést kell megőrizniük a visszamenőleges kompatibilitás érdekében.
A kivételek eldobásakor elkerülendő dolgok
Az alábbi lista azonosítja a kivételekkel elkerülhető eljárásokat:
- Ne használjon kivételeket egy program folyamatának módosításához a szokásos végrehajtás részeként. Használjon kivételeket a hibafeltételek jelentéséhez és kezeléséhez.
- A kivételeket nem szabad visszatérési értékként vagy paraméterként visszaadni ahelyett, hogy kidobták volna őket.
- Ne dobjonSystem.Exception, System.SystemExceptionSystem.NullReferenceExceptionne System.IndexOutOfRangeException vagy szándékosan a saját forráskódjából.
- Ne hozzon létre kivételeket, amelyek hibakeresési módban, de kiadási módban nem hozhatók létre. A fejlesztési fázisban előforduló futásidejű hibák azonosításához használja inkább a Hibakeresési jogérvényesítést.
Kivételek a feladatvisszaküldött metódusokban
A módosítóval async
deklarált metódusoknak különleges szempontokat kell figyelembe venniük a kivételek tekintetében. A metódusban async
alkalmazott kivételek a visszaadott tevékenységben vannak tárolva, és csak akkor jelennek meg, ha például a feladatra várni kell. A tárolt kivételekről további információt az Aszinkron kivételek című témakörben talál.
Javasoljuk, hogy a metódusok aszinkron részeinek megadása előtt ellenőrizze az argumentumokat, és adjon meg minden megfelelő kivételt, például ArgumentException és ArgumentNullException. Vagyis ezeknek az érvényesítési kivételeknek szinkron módon kell megjelenniük a munka megkezdése előtt. Az alábbi kódrészlet egy példát mutat be, ahol a kivételek ki lettek dobva, a ArgumentException kivételek szinkron módon jelennek meg, míg a InvalidOperationException visszaadott feladat tárolja őket.
// Non-async, task-returning method.
// Within this method (but outside of the local function),
// any thrown exceptions emerge synchronously.
public static Task<Toast> ToastBreadAsync(int slices, int toastTime)
{
if (slices is < 1 or > 4)
{
throw new ArgumentException(
"You must specify between 1 and 4 slices of bread.",
nameof(slices));
}
if (toastTime < 1)
{
throw new ArgumentException(
"Toast time is too short.", nameof(toastTime));
}
return ToastBreadAsyncCore(slices, toastTime);
// Local async function.
// Within this function, any thrown exceptions are stored in the task.
static async Task<Toast> ToastBreadAsyncCore(int slices, int time)
{
for (int slice = 0; slice < slices; slice++)
{
Console.WriteLine("Putting a slice of bread in the toaster");
}
// Start toasting.
await Task.Delay(time);
if (time > 2_000)
{
throw new InvalidOperationException("The toaster is on fire!");
}
Console.WriteLine("Toast is ready!");
return new Toast();
}
}
Kivételosztályok definiálása
A programok előre definiált kivételosztályt állíthatnak be a System névtérbe (kivéve, ha korábban feljegyezték), vagy létrehozhatják saját kivételosztályaikat a forrásból Exceptionvaló származtatással. A származtatott osztályoknak legalább három konstruktort kell meghatározniuk: egy paraméter nélküli konstruktort, egy olyant, amely beállítja az üzenettulajdonságot, és egyet, amely mind a tulajdonságokat, mind a MessageInnerException tulajdonságokat beállítja. Példa:
[Serializable]
public class InvalidDepartmentException : Exception
{
public InvalidDepartmentException() : base() { }
public InvalidDepartmentException(string message) : base(message) { }
public InvalidDepartmentException(string message, Exception inner) : base(message, inner) { }
}
Új tulajdonságok hozzáadása a kivételosztályhoz, ha az általuk megadott adatok hasznosak a kivétel feloldásához. Ha új tulajdonságokat ad hozzá a származtatott kivételosztályhoz, ToString()
felül kell bírálni a hozzáadott adatok visszaadásához.
C# nyelvspecifikáció
További információ: Kivételek és A dobás utasítás a C# nyelvi specifikációjában. A nyelvi specifikáció a C#-szintaxis és -használat végleges forrása.
Lásd még
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: