Следует ли вызывать GC.SuppressFinalize для объектов, у которых нет финализатора?
Вопрос
По какой-то причине FXCop, кажется, думает Мне следует вызывать GC.SuppressFinalize в Dispose, независимо от того, есть ли у меня финализатор или нет.
Я что-то пропустил?Есть ли причина вызывать GC.SuppressFinalize для объектов, для которых не определен финализатор?
Решение
В IL всегда есть финализатор - System.Object.Finalize () существует в каждом классе, поэтому, если вы создаете собственный класс, у него есть финализатор, который вы хотите подавить. При этом не все объекты помещаются в очередь на финализацию, поэтому вам нужно только технически подавлять финализацию, если вы реализуете свой собственный финализатор.
Если вы реализуете IDisposable
для переноса неуправляемых ресурсов, вы должны включить финализатор, и вы должны запретить его запуск, поскольку в теории вы уже выполняете очистку, когда Dispose
называется.
Другие советы
Нет необходимости звонить GC.SuppressFinalize(this)
в Dispose, если:
- Вы — базовый класс, реализующий виртуальные методы Dispose, предназначенные для переопределения (опять же, даже здесь это может не быть вашей ответственностью, но в этом случае вы можете захотеть это сделать).
- У вас есть финализатор.Технически, каждый класс в .NET имеет финализатор, но если единственный присутствующий финализатор — это тот, который находится в
Object
, то считается, что объект не требует финализации и не помещается в список финализации при сборке мусора.
Я бы сказал, что если у вас нет ни одного из вышеперечисленных случаев, вы можете смело игнорировать это сообщение.
Все объекты имеют метод финализатора, даже если вы не реализовали его с помощью деструктора c # (который на самом деле не гарантированно вызывается GC). Это просто хорошая практика, чтобы подавить вызов, если вы внедрили IDisposable, потому что это означает, что вы решили выполнить финализацию явно.
Я не вижу необходимости вызывать SuppressFinalize (), если финализатор не определен. Если вы хотите быть защитником, тогда может быть полезно иметь финализатор и Dispose (), поэтому вам не нужно полагаться на клиентов, которые всегда вызывают Dispose (). Тогда вы не потеряете ресурсы, когда они забудут.