IDisposable è un'interfaccia in C# che rappresenta un oggetto che può essere liberato da risorse non gestite. Gli oggetti che implementano IDisposable possono essere utilizzati all'interno di un blocco "using" in C#, il quale garantisce che il metodo Dispose() venga chiamato alla fine del blocco, liberando le risorse non gestite. In generale, gli oggetti che utilizzano risorse non gestite, come file, connessioni di rete, ecc., dovrebbero implementare IDisposable.
Vediamo come poter implementare correttamente l'interfaccia IDisposable.
Implement IDisposable
Implementare questa interfaccia è utile e consigliato per gestire al meglio le nostre risorse.
Vi mostrerò una classe tipo che implementa il minimo indispensabile:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MyNameSpace
{
public class MyClass : IDisposable
{
#region Attributes
/// <summary>
/// Variable to track if Dispose has been called
/// </summary>
private bool disposed = false;
#endregion Attributes
#region Constructors
/// <summary>
/// Costruttore
/// </summary>
public MyClass()
{
}
#endregion Constructors
#region Methods
.....
#endregion Methods
#region Dispose
/// <summary>
/// Dispose resource
/// </summary>
public void Dispose()
{
// Check if Dispose has already been called
if (!disposed)
{
// Call the overridden Dispose method that contains common cleanup code
// Pass true to indicate that it is called from Dispose
Dispose(true);
GC.SuppressFinalize(this);
}
}
/// <summary>
/// // NOTE: Leave out the finalizer altogether if this class doesn't
/// own unmanaged resources itself, but leave the other methods
/// exactly as they are.
/// </summary>
~MyClass()
{
// Finalizer calls Dispose(false)
Dispose(false);
}
/// <summary>
/// The bulk of the clean-up code is implemented in Dispose(bool)
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// dispose-time code
}
// finalize-time code
}
#endregion Dispose
}
}
Questa classe vi mostra esattamente cosa fare.
Il metodo Dispose() viene invocato automaticamente?
No. In generale questo metodo non viene invocato in automatico.
Solo se è presente il metodo Finalize viene invocato quando parte il garbage collector.
Ovvero il Garbage Collector chiama i vari distruttori tra cui ~MyClass() e questo a sua volta chiamerà la Dispose().
Una maniera per chiamare la dispose in maniera autoamtica è l'uso del costrutto using...
using (MyClass mc = new MyClass())
{
if (mc != null)
{
return;
}
}
Quando si esce dal costrutto using la Dispose() viene chiamata in automatico.
Buon lavoro!