Как реализовать одноразовый шаблон в классе, который наследуется от другого одноразового класса? - PullRequest
3 голосов
/ 03 апреля 2010

Я часто использовал одноразовый шаблон в простых классах, которые ссылались на небольшое количество ресурсов, но мне никогда не приходилось реализовывать этот шаблон в классе, который наследуется от другого одноразового класса, и я начинаю немного запутываться в том, как освободить целые ресурсы.

Я начинаю с небольшого примера кода:

public class Tracer : IDisposable
{
    bool disposed;
    FileStream fileStream;

    public Tracer()
    {
        //Some fileStream initialization
    }

    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                if (fileStream != null)
                {
                    fileStream.Dispose();
                } 
            }

            disposed = true; 
        }
    }
}

public class ServiceWrapper : Tracer
{
    bool disposed;
    ServiceHost serviceHost;

    //Some properties

    public ServiceWrapper ()
    {
        //Some serviceHost initialization
    }

    //protected override void Dispose(bool disposing)
    //{
    //    if (!disposed)
    //    {
    //        if (disposing)
    //        {
    //            if (serviceHost != null)
    //            {
    //                serviceHost.Close();
    //            } 
    //        }

    //        disposed = true;
    //    }
    //}
}

Мой реальный вопрос: как реализовать одноразовый шаблон внутри моего класса ServiceWrapper, чтобы быть уверенным, что когда я буду располагать его экземпляром, он будет располагать ресурсами как в унаследованном, так и в базовом классе?

Спасибо.

Ответы [ 4 ]

3 голосов
/ 03 апреля 2010

Я видел, как это делалось несколькими способами:

  1. В переопределенном производном классе Dispose (удаление bool) очистите ваши вещи и затем вызовите базовый класс Dispose (удаление bool). Проблема здесь в том, что базовый класс уже имеет переменную gate gate и проверки, которые необходимо будет реплицировать.

  2. Создайте защищенный метод Очистки, который Dispose (удаление bool) в вызовах базового класса фактически выполняет очистку. Производный класс может переопределить его, выполнить очистку и вызвать метод очистки базового класса. Это оставляет все удаленные проверки в базовом классе, которые не должны быть реплицированы.

2 голосов
/ 27 января 2011

У вас есть некоторые проблемы, во-первых, вы не определяете финализатор, но вызываете GC.Suppressfinalizer. также вы устанавливаете утилизацию неверным способом, и, кроме того, ваша утилизация не является поточно-ориентированной.

Я использую базовый класс disposed, который реализует IDispose вместе с множеством других вспомогательных методов.

public class Disposable : IDisposable
{
    private object _lock = new object();

    ~Disposable()
    {
        try
        {
            Dispose(false);
        }
        catch
        {

        }
    }

    protected void ThrowIfDisposed()
    {
        if (IsDisposed)
        {
            throw new ObjectDisposedException(GetType().FullName);
        }
    }

    public bool IsDisposed { get; private set; }

    protected virtual void Dispose(bool disposing)
    {

    }

    public void Dispose()
    {
        lock (_lock)
        {
            if (!IsDisposed)
            {
                Dispose(true);
                IsDisposed = true;
                GC.SuppressFinalize(this);
            }
        }
    }
}
1 голос
/ 03 апреля 2010

Посмотрите на эту запись в блоге Дэви Брайона: http://davybrion.com/blog/2008/06/disposing-of-the-idisposable-implementation/

Он добавляет немного дополнительного кода к родительскому классу, но выполнение соответствующей очистки в подклассе становится довольно простым.

0 голосов
/ 03 апреля 2010

Унаследованный класс ServiceWrapper наследуется от класса, реализующего IDisposable, поэтому SericeWrapper также реализует IDisposable. Для доказательства, новый экземпляр ServiceWrapper. Вы обнаружите (с intellisense), что он тоже имеет метод Dispose ().

...