Sobes.tech
Middle

Какво е интерфейсът IDisposable и за какво се използва в C#?

sobes.tech AI

Отговор от AI

IDisposable — това е интерфейс, който предоставя механизъм за освобождаване на неуправляеми ресурси. Той съдържа метод Dispose().

Използва се за:

  • Освобождаване на неуправляеми ресурси: като файлови дескриптори, връзки с бази данни, мрежови сокети. .NET не може автоматично да управлява тези ресурси.
  • Почистване след използване: гарантира, че ресурсно-интензивните обекти ще бъдат правилно освободени, дори ако възникнат изключения.
  • Съвместна употреба с оператора using: операторът using автоматично извиква метода Dispose() при изход от блока код, дори ако възникне изключение. Това е предпочитаният начин за използване на обекти, реализиращи IDisposable.

Пример за реализация:

public class MyResource : IDisposable
{
    // Имитация на неуправляем ресурс
    private bool isDisposed = false;
    private IntPtr unmanagedPointer;

    public MyResource()
    {
        // Заделяне на неуправляем ресурс
        unmanagedPointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(100);
    }

    // Метод Dispose от интерфейса IDisposable
    public void Dispose()
    {
        Dispose(true);
        // Отмяна на финализирането, тъй като ресурсите вече са освободени
        GC.SuppressFinalize(this);
    }

    // Виртуален метод за реализиране на логиката за освобождаване
    protected virtual void Dispose(bool disposing)
    {
        if (!isDisposed)
        {
            if (disposing)
            {
                // Освобождаване на управлявани ресурси, ако има
                // ...
            }

            // Освобождаване на неуправляеми ресурси
            System.Runtime.InteropServices.Marshal.FreeHGlobal(unmanagedPointer);
            unmanagedPointer = IntPtr.Zero;

            isDisposed = true;
        }
    }

    // Финализатор (деструктор) за освобождаване на ресурси, ако `Dispose` не е бил извикан явно
    ~MyResource()
    {
        Dispose(false);
    }
}

Пример за използване с using:

using (var resource = new MyResource())
{
    // Работа с ресурса
    // ...
} // `Dispose()` се извиква автоматично при изход от блока `using`