В С# в чем разница между деструктором и методом Finalize в классе?

В чем разница, если таковая существует, между деструктором и методом Finalize в классе?

Недавно я обнаружил, что Visual Studio 2008 считает деструктор синонимом метода Finalize, что означает, что Visual Studio не позволит вам одновременно определять оба метода в классе.

Например, следующий фрагмент кода:

class TestFinalize
{
    ~TestFinalize()
    {
        Finalize();
    }

    public bool Finalize()
    {
        return true;
    }
}

Дает следующую ошибку при вызове Finalize в деструкторе:

Вызов неоднозначен между следующими методами или свойствами:         'TestFinalize. ~ TestFinalize()' и 'TestFinalize.Finalize()'

И если комментарий Finalize закомментирован, он дает следующую ошибку:

Тип 'ManagementConcepts.Service.TestFinalize' уже определяет член, называемый      "Завершить" с теми же параметрами

Ответ 1

Деструктор в С# переопределяет метод System.Object.Finalize. Для этого необходимо использовать синтаксис деструктора. В ручном переопределении Finalize появится сообщение об ошибке.

В основном то, что вы пытаетесь сделать с объявлением метода Finalize, - hiding, метод базовый класс. Это заставит компилятор выпустить предупреждение, которое можно отключить с помощью модификатора new (если он будет работать). Здесь важно отметить, что вы не можете и override и объявляете член new с одинаковым именем одновременно, поэтому при вызове метода деструктора и Finalize в ошибке (но вы можете, хотя и не рекомендуется, объявить метод public new void Finalize(), если вы не объявляете деструктор).

Ответ 2

В Википедии есть хорошее обсуждение разницы между финализатором и destructor в finalizer.

На С# действительно нет "истинного" деструктора. Синтаксис напоминает деструктор С++, но он действительно является финализатором. Вы правильно написали это в первой части вашего примера:

~ClassName() { }

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

В соответствии с Microsoft финализатор ссылается на функцию, которую собирает сборщик мусора, когда он собирает (Finalize), тогда как деструктор ваш бит кода, который выполняется в результате (синтаксический сахар, который становится Finalize). Они настолько близки к тому, что Microsoft никогда не делала различий.

Использование терминалом "деструктор" в С++ используется в качестве вводящего в заблуждение, поскольку в С++ оно выполняется в том же потоке, как только объект удаляется или удаляется из стека, а в С# он выполняется в отдельном потоке в другом время.

Ответ 3

Найдено здесь: http://sanjaysainitech.blogspot.com/2007/06/difference-between-destructor-dispose.html

  • Destructor

    Это специальные методы, которые содержат код очистки для объекта. Вы не можете вызывать их явно в своем коде, поскольку они вызываются неявно с помощью GC. В С# у них есть то же имя, что и имя класса знаком ~. Как -

    Class MyClass
    {
    
    ~MyClass()
    {
    .....
    }
    }
    

    В VB.NET деструкторы реализуются путем переопределения Finalize метод класса System.Object.

  • Dispose

    Они похожи на любые другие методы в классе и могут быть вызваны явно, но у них есть особая цель для очистки объекта. В методе dispose мы записываем код очистки для объекта. это важно, чтобы мы освободили все неуправляемые источники в распоряжении метод, такой как соединение с базой данных, файлы и т.д. метод dispose должен реализовывать интерфейс IDisposable. Метод Dispose должен вызвать метод GC.SuppressFinalize для объекта, которым он является если класс имеет деструктор, потому что он уже сделал работа по очистке объекта, тогда это не обязательно для мусора сборщик для вызова объекта Метод завершения. Справка: http://msdn2.microsoft.com/en-us/library/aa720161(VS.71).aspx

  • Доработка

    Метод Finalize служит защитой для очистки ресурсов в что ваш метод Dispose не вызывается. Вы должны внедрить метод Finalize для очистки неуправляемых ресурсов. Вы не должен реализовывать метод Finalize для управляемых объектов, поскольку сборщик мусора автоматически очищает управляемые ресурсы. Метод Finalize вызывается GC неявно, поэтому вы не можете вызовите его из своего кода.

    Примечание.. В С# метод Finalize не может быть переопределен, поэтому вам нужно использовать деструктор, внутренняя реализация которого переопределит Метод finalize в MSIL. Но в VB.NET метод Finalize может быть переопределить, потому что он поддерживает метод деструктора.

Обновление: Интересная полусвязанная тема здесь.