IDisposable - правильный путь реализации (c #) - PullRequest
1 голос
/ 01 декабря 2011

Я не совсем понимаю, когда и как реализовать IDisposable.

Я увидел, что необходимо реализовать IDIsposable только для класса, который содержит неуправляемые ресурсы

поэтому, если у меня есть класс "A", который содержит неуправляемые и управляемые ресурсы, и я реализую IDisposable для неуправляемых ресурсов, включая GC.SuppressFinalize (this), то как очистить управляемые ресурсы, если GC теперь не будет вызывать финализатор для моего класс

Я действительно буду признателен, если кто-нибудь сможет сделать IDisposable более понятным для меня (когда и как использовать)

Ответы [ 3 ]

1 голос
/ 01 декабря 2011
  • когда часть, очень упрощенная: вы должны реализовать IDisposable, когда ваш класс «владеет» (что иногда бывает не так явно) другими IDisposable или неуправляемыми ресурсами, которые нуждаются в очистке
    public class AClass : IDisposable 
    {
    public void Dispose() 
    {
        Dispose(true);
        GC.SuppressFinalize(this); 
    }
    
    protected virtual void Dispose(bool disposing)
    {
        if (disposing) 
        {
        // Free managed objects.
        }
        // Free unmanaged objects.
    }
    
    ~AClass() 
    {
     // Simply call Dispose(false).
         Dispose (false);
    }
    

    }

Дополнительная информация:
http://www.codeproject.com/KB/dotnet/IDisposable.aspx
http://blogs.msdn.com/b/kimhamil/archive/2008/11/05/when-to-call-dispose.aspx

1 голос
/ 01 декабря 2011

Это неверно.Вы также можете реализовать IDispose для управляемых классов.Если у вас есть только управляемые ресурсы, а ваш клиент не вызывает Dispose, сборщик мусора в какой-то момент освободит ресурсы.Однако, если вы хотите освободить ресурсы раньше (например, закрыть файл или подключение к базе данных), сделайте это с помощью собственного метода Dispose.

Вам не следует беспокоиться о GC.SuppressFinalize, если выесть финализатор.И если у вас есть финализатор, постарайтесь его не иметь - гораздо лучше не попадать в этот регион, если вам абсолютно не нужно.

0 голосов
/ 01 декабря 2011

Уникальная особенность интерфейса IDisposable заключается в том, что язык фактически предоставляет для него определенную конструкцию: блок «using»:

public void SomeMethod()
{
    using(IDisposable myDisposable = new SomeClassThatImplementsIDisposable())
    {
        //Do something with your disposable...
    }
    //And, it's out of scope here
}

Это немного синтаксического сахара, в котором то, что происходит на самом делеthis:

public void SomeMethod()
{
    IDisposable myDisposable = new SomeClassThatImplementsIDisposable();
    try 
    {    
        //Do something with your disposable...
    }
    finally
    {
        myDisposble.Dispose();
    }
    //And, it's out of scope here
}

Итак, когда вы реализуете IDisposable, вы предоставляете клиентам вашего класса способ использовать его там, где они могут гарантировать (по большей части), что очистка, которую вы планируете для своего класса на самом делеслучается.

Это наиболее часто встречающееся и критическое в классах, которые содержат неуправляемые ресурсы.Например, если бы ваш класс содержал соединение с базой данных, вы бы не хотели, чтобы клиенты выходили за его пределы, даже не закрывая соединение, поскольку это было бы утечкой памяти.Использование IDisposable выше также гарантирует, что если генерируется какое-то исключение, «finally», подразумеваемое «using ()», вызовет ваше распоряжение, чтобы вы могли хотя бы очистить.

Тем не менее, безусловно, естьситуации, когда вы можете использовать его для управляемых ресурсов.Один пример, который приходит на ум с самого начала, - это если экземпляр вашего класса слушает события, вызванные экземпляром класса с более длительным сроком жизни, чем ваш.Без утилизации это также создает утечку памяти (распространенная проблема в .NET).

Так что, вообще говоря, я бы использовал ее в обстоятельствах, когда было бы плохо, если экземпляр вашего класса вышел изобласть без выполнения всего кода очистки.Реализация IDisposable объявляет всем клиентам вашего класса, что есть ресурсы, которые он содержит, и которые необходимо правильно утилизировать.

...