Расположение объектов в Деструкторе

У меня есть объект, который имеет доступный объект как участника.

public class MyClass
{
    private MyDisposableMember member;

    public DoSomething
    {
         using (member = new MyDisposableMember())
         {
             // Blah...
         }
    }
}

Может быть много методов в MyClass, все требование a using оператор. Но что, если я сделал это вместо этого?

public class MyClass
{
    private MyDisposableMember member = new MyDisposableMember();

    public DoSomething
    {
         // Do things with member :)
    }

    ~MyClass()
    {
        member.Dispose();
    }
}

Как видете, member располагается в деструкторе. Это работало бы? Есть ли какие-либо проблемы с этим подходом?

5
задан Robert Harvey 1 March 2010 в 17:51
поделиться

6 ответов

В идеале Dispose () должен быть вызван до завершения. Было бы лучше следовать типичному шаблону удаления и позволить пользователю правильно использовать Dispose () для объекта и иметь финализатор Dispose , если dispose еще не был вызван .

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

11
ответ дан 18 December 2019 в 07:08
поделиться

НЕ ДЕЛАЙТЕ ЭТОГО!

Сборщик мусора сделает это за вас (косвенно, поскольку объект для удаления или другой объект будет содержать деструктор).

MyDisposableMember может быть удален сборщиком мусора даже до того, как вы его удалите - то, что происходит тогда, может быть не тем намеревался сделать.

Еще хуже: добавление деструктора (или финализатора) к классу требует дополнительного времени при удалении объекта (гораздо больше времени, поскольку объект будет оставаться в памяти как минимум в течение одного цикла сбора и, возможно, даже будет переведен в следующее поколение) .

Следовательно, это было бы совершенно бесполезно и даже привело бы к обратным результатам.

3
ответ дан 18 December 2019 в 07:08
поделиться

Лучше всего следовать шаблону Microsoft, чтобы пользователи вашего класса имели полный контроль над его удалением.

public class MyClass : IDisposable
{
    private MyDisposableMember member = new MyDisposableMember();

    public DoSomething
    {
         // Do things with member :)
    }

    ~MyClass()
    {
        Dispose(false);
    }

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

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)  // Release managed resources
        {           
            member.Dispose();
        }

        // Release unmanaged resources
    }
}
0
ответ дан 18 December 2019 в 07:08
поделиться

Единственное, что я вижу не так (и это не ошибка), так это то, что в операторе using вы явно удаляете объект в этот момент вовремя (когда вызывается ваша функция / метод). Деструктор не может быть вызван, они вызываются автоматически. Таким образом, на этом этапе может потребоваться некоторое время, чтобы избавиться от участника. Лучше реализовать интерфейс IDisposeable для MyClass.

0
ответ дан 18 December 2019 в 07:08
поделиться

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

В более общем случае вам следует поместить всю логику утилизации в Dispose() и реализовать IDisposable, а затем использовать ваш класс вместе с using или try-finally

.
1
ответ дан 18 December 2019 в 07:08
поделиться

Вам, вероятно, следует сделать MyClass реализацией IDisposable . Внутри метода Dispose () вызовите member.Dispose (); . Таким образом, программист может контролировать, когда член будет удален.

7
ответ дан 18 December 2019 в 07:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: