====== Rozhraní IDisposable a blok using ======
V prostředí .NET se o řízenou paměť stará [[it:sw:garbage_collector|Garbage Collector]]. Nicméně u vnějších zdrojů, jako jsou soubory nebo síťová připojení, musí programátor zajistit jejich uvolnění manuálně. K tomu slouží standardizovaný vzor pomocí rozhraní **IDisposable**.
===== 1. Co je IDisposable? =====
Jedná se o rozhraní obsahující jedinou metodu: `Dispose()`. Pokud třída toto rozhraní implementuje, signalizuje tím, že drží zdroje, které by měly být po ukončení práce explicitně uvolněny.
public class MujZapisovac : IDisposable {
public void Dispose() {
// Logika pro uvolnění neřízených zdrojů (např. zavření souboru)
}
}
---
===== 2. Problém bez uvolnění =====
Pokud zapomenete zavolat `Dispose()`, zdroj zůstane v operačním systému "otevřený" nebo "zamčený".
* **Příklad:** Otevřete soubor pro zápis. Pokud ho neuzavřete, žádná jiná aplikace (ani váš program při dalším spuštění) k němu nemusí získat přístup, dokud proces aplikace úplně neskončí.
---
===== 3. Konstrukce using =====
Zajištění, aby se `Dispose()` zavolal i v případě, že v kódu dojde k chybě (výjimce), je pomocí bloků `try-finally` pracné. Jazyk C# proto nabízí klíčové slovo **using**, které tento proces automatizuje.
==== Klasický blok using ====
Zaručuje, že metoda `Dispose()` bude zavolána ihned poté, co program opustí složené závorky.
using (var soubor = new StreamWriter("denik.txt")) {
soubor.WriteLine("Ahoj světe");
} // Zde se automaticky volá soubor.Dispose()
==== Using deklarace (C# 8.0+) ====
Moderní a stručnější zápis. Objekt se uvolní automaticky na konci bloku (např. na konci metody), ve kterém byl deklarován.
public void ZapiseData() {
using var soubor = new StreamWriter("denik.txt");
soubor.WriteLine("Nová data");
} // soubor.Dispose() se zavolá automaticky zde
---
===== 4. Vztah ke Garbage Collectoru =====
GC neví, že váš objekt drží zámek na soubor. On vidí pouze malý objekt v paměti.
* Pokud zavoláte `Dispose()`, uvolníte neřízený zdroj **okamžitě**.
* Pokud na to zapomenete, zdroj se uvolní až tehdy, kdy GC objekt úplně odstraní z paměti (což může trvat velmi dlouho).
---
===== 5. Kdy IDisposable implementovat? =====
Vlastní třídu byste měli implementovat jako `IDisposable`, pokud:
1. Přímo využívá neřízené zdroje (práce s Win32 API, ukazatele).
2. Obsahuje jako své členy (fields) jiné objekty, které jsou samy o sobě `IDisposable` (např. `SqlConnection`, `HttpClient`, `FileStream`).
----
//Související články://
* [[it:sw:garbage_collector|Garbage Collector]]
* [[it:sw:stack_vs_heap|Stack vs. Heap (Zásobník vs. Halda)]]
* [[it:sw:exception_handling|Zpracování výjimek v .NET]]
//Tagy: {{tag>programming dot-net csharp memory-management resources idisposable}}//