Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
V jazyce C# se chyby v programu za běhu šíří prostřednictvím programu pomocí mechanismu označovaného jako výjimky. Výjimky jsou vyvolány kódem, který narazí na chybu a zachytil kód, který může chybu opravit. Výjimky můžou vyvolat modul runtime .NET nebo kód v programu. Jakmile dojde k vyvolání výjimky, propaguje se po zásobníku volání, dokud není nalezen příkaz pro výjimku catch
. Nezachycené výjimky zpracovává obecný zpracovatel výjimek poskytovaný systémem, která zobrazuje dialogové okno.
Výjimky jsou reprezentovány třídami odvozenými z Exception. Tato třída identifikuje typ výjimky a obsahuje vlastnosti s podrobnostmi o výjimce. Vyvolání výjimky zahrnuje vytvoření instance odvozené třídy výjimky, volitelně konfigurace vlastností výjimky a následné vyvolání objektu pomocí klíčového throw
slova. Například:
class CustomException : Exception
{
public CustomException(string message)
{
}
}
private static void TestThrow()
{
throw new CustomException("Custom exception in TestThrow()");
}
Po vyvolání výjimky modul runtime zkontroluje aktuální příkaz a zjistí, jestli je v try
bloku. Pokud ano, zkontrolují se všechny catch
bloky přidružené k try
bloku a zkontrolují, jestli můžou výjimku zachytit.
Catch
bloky obvykle určují typy výjimek; pokud je typ catch
bloku stejný typ jako výjimka nebo základní třída výjimky, catch
může blok zpracovat metodu. Například:
try
{
TestThrow();
}
catch (CustomException ex)
{
System.Console.WriteLine(ex.ToString());
}
Pokud příkaz, který vyvolá výjimku, není v try
bloku nebo pokud try
blok, který ho uzavírá, nemá žádný odpovídající catch
blok, modul runtime zkontroluje metodu, která ho volá, pro příkaz try
a bloky catch
. Modul runtime pokračuje v zásobníku volání a hledá kompatibilní catch
blok. Po nalezení a spuštění bloku catch
je řízení předáno dalšímu příkazu po tomto bloku catch
.
Příkaz try
může obsahovat více než jeden catch
blok. První catch
příkaz, který dokáže zpracovat výjimku, se spustí. Všechny následující catch
příkazy, i když jsou kompatibilní, se ignorují. Uspořádejte bloky zachytávání od nejvíce specifických (nebo nejvíce odvozených) po nejméně specifické. Například:
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");
}
}
}
Před spuštěním catch
bloku modul runtime kontroluje finally
bloky.
Finally
bloky umožňují programátoru vyčistit jakýkoli nejednoznačný stav, který by mohl být ponechán z přerušeného try
bloku, a uvolnit veškeré externí prostředky (například grafické popisovače, připojení k databázi nebo streamy souborů), aniž bychom čekali na to, až modul runtime dokončí uvolnění objektů. Například:
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");
}
}
Pokud WriteByte()
vyvoláte výjimku, kód ve druhém try
bloku, který se pokusí znovu otevřít soubor, selže, pokud file.Close()
není volána, a soubor zůstane uzamčený. Jelikož se bloky finally
spouští i tehdy, když je vyvolána výjimka, blok finally
v předchozím příkladu umožňuje správné uzavření souboru a pomáhá vyhnout se chybě.
Pokud se v zásobníku volání po vyvolání výjimky nenajde žádný kompatibilní catch
blok, dojde k jedné ze tří věcí:
- Pokud je výjimka ve finalizátoru, finalizátor je přerušen a, pokud existuje, je volán jeho základní finalizátor.
- Pokud zásobník volání obsahuje statický konstruktor nebo inicializátor statického pole, je vyvolána výjimka TypeInitializationException, přičemž původní výjimka je přiřazena k vlastnosti InnerException nové výjimky.
- Pokud je dosaženo začátku vlákna, vlákno se ukončí.