Middle
Jaký je rozdíl mezi metodami Dispose a Finalize?
sobes.tech AI
Odpověď od AI
Dispose je explicitně voláno vývojářem nebo prostředím (například using) za účelem uvolnění neřízených zdrojů. Finalize (přes destruktor v C#) je voláno sběračem odpadků při zničení objektu, pokud nebyl explicitně uvolněn.
| Kritérium | Dispose | Finalize (přes destruktor) |
|---|---|---|
| Volání | Explicitně definováno vývojářem (using, Dispose()) |
Automaticky sběračem odpadků |
| Doba běhu | Deterministická | Nedeterministická (závisí na sběrači odpadků) |
| Účel | Uvolnění jak řízených, tak neřízených zdrojů | Uvolnění pouze neřízených zdrojů |
| Implementace | Implementace rozhraní IDisposable |
Přepsání metody Object.Finalize (přes destruktor) |
| Použití | Preferovaný způsob uvolnění zdrojů | Záložní mechanismus pro neřízené zdroje, pokud Dispose nebyl volán |
Příklad použití using (automatické volání Dispose):
// Příklad třídy implementující `IDisposable`
using (var fileStream = new System.IO.FileStream("myfile.txt", System.IO.FileMode.Open))
{
// Práce se souborem
} // Zde je automaticky voláno `fileStream.Dispose()`
Příklad třídy s IDisposable a destruktor:
using System;
public class MyDisposableClass : IDisposable
{
private IntPtr unmanagedResource; // Neřízený zdroj
private bool disposed = false;
public MyDisposableClass()
{
// Inicializace neřízeného zdroje
unmanagedResource = System.Runtime.InteropServices.Marshal.AllocHGlobal(100);
Console.WriteLine("Zdroj alokován.");
}
// Implementace `IDisposable`
public void Dispose()
{
Dispose(true);
// Potlačení finalizace, protože zdroj již byl uvolněn
GC.SuppressFinalize(this);
Console.WriteLine("Dispose() voláno.");
}
// Chráněná virtuální metoda pro uvolnění zdrojů
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Uvolnění řízených zdrojů (pokud jsou)
Console.WriteLine("Uvolnění řízených zdrojů.");
}
// Uvolnění neřízených zdrojů
if (unmanagedResource != IntPtr.Zero)
{
System.Runtime.InteropServices.Marshal.FreeHGlobal(unmanagedResource);
unmanagedResource = IntPtr.Zero;
Console.WriteLine("Neřízený zdroj uvolněn.");
}
disposed = true;
}
}
// Destruktor (finalizátor)
~MyDisposableClass()
{
Dispose(false); // Uvolní pouze neřízené zdroje
Console.WriteLine("Finalizátor volán.");
}
}
Metoda Dispose musí být implementována ve všech třídách, které spravují neřízené zdroje (soubory, síťová spojení, deskriptory atd.). Finalize by měl být používán jako záložní mechanismus pro uvolnění neřízených zdrojů v případě, že Dispose nebyl volán. Třídy implementující Finalize by měly jeho volání potlačit v Dispose(true), aby se zabránilo duplicitnímu uvolnění zdrojů.