Использование финализатора для логики c, когда он вызывается - PullRequest
1 голос
/ 08 февраля 2020

Можно ли использовать финализатор класса для чего-то еще, кроме освобождения ресурсов? Я читал, что он вызывается, когда G C хочет удалить объект из памяти, что очень плохо c (я понимаю, почему, но это ограничивает его использование). Можно ли надежно использовать финализатор для создания logi c, который должен произойти, когда переменная выходит из области видимости? Если финализатор не подходит для этого, как его достичь?

Моя идея в основном такая же, как деструктор объекта, который в c ++ будет размещен в стеке, поэтому его деструктор нужно вызывать когда это выходит за рамки. Или есть способ заставить объект в стеке, чтобы он вел себя так же? Или, может быть, блок using(...) и методы утилизации могут быть использованы для достижения чего-то подобного?

Ответы [ 2 ]

1 голос
/ 08 февраля 2020

Помимо опубликованных ссылок, вы идете против дизайна и можете столкнуться с множеством странных вещей, если продолжите идти по этому пути.

Если вы хотите повторить поведение c ++ RAII, просто используйте ключевое слово using с доступными ресурсами.

C# 8 предоставляет возможность объявлять using var переменные, просто syntacti c sugar, которые синтаксически делают код максимально приближенным к c ++ RAII.

Eri c Ссылки Липперта объясняют, что происходит под капотом, ясно, что это дает вам понимание, но при выезде с спроектированной дороги ничего договорного нет.

1 голос
/ 08 февраля 2020

В C# вам не нужно напрямую использовать финализатор. Он вызывается G C для очистки только неуправляемых ресурсов, если таковые имеются. Технически финализуемый объект добавляется в отдельную очередь и завершается в отдельном потоке перед сборкой мусора. Тем не менее, это базовый поток c, и вам не нужно полагаться на него.

Eri c Липперт написал две очень хорошие статьи о финализаторах под капотом: это и это , обратитесь к ним, чтобы увидеть возможные подводные камни здесь. Финализаторы вызываются в недетерминированном порядке c, вы никогда не должны выполнять какие-либо логические операции c зависит от других объектов внутри финализатора.

Для ваших целей вы можете реализовать интерфейс IDisposable и очистить ресурсы явно посмотрите MSDN guide для подробностей.

Очень простой пример приведен ниже

public class MyResource : IDisposable
{
    // managed resource this class uses.
    private readonly Component _component = new Component();
    private bool _disposed;

    public void Dispose()
    {
        if (!_disposed)
        {
            // Dispose managed resources.
            _component.Dispose();
            _disposed = true;
        }
        //tell CLR to prevent finalization, since it's already done
        GC.SuppressFinalize(this);
    }
}

Если ваш класс использует только управляемые ресурсы, вам не нужно использовать финализатор, вы просто реализуете метод Dispose() для очистки управляемые ресурсы.

Объект, реализующий IDisposable, может использоваться в операторе using или в блоке try/finally в соответствии с с использованием объекта, реализующего IDisposable

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...