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