Финализаторы - это боль, и вам следует избегать, чтобы они назывались , называемыми , если это возможно. Однако если вы реализовали IDisposable, вы почти всегда захотите написать его (в сочетании с методом Dispose (bool)). Это вызывает Dispose (false) и GC.SuppressFinalize ().
Если вы не реализуете финализатор, то, если в каких-либо IDisposable экземплярах, которые вы правильно удерживаете, финализаторы реализуются, вы пропустите. Скажем, например, что у SafeHandle не было финализатора, а кто-то вызывал Dispose? Если вы держите его и не внедрили финализатор, то вы позволяете своему потребителю навсегда утратить дескриптор, не вызывая Dispose для вас!
Если предположить, что и ваш потребитель, и предметы, которые вы потребляете, будут играть хорошо, это не повод не играть себя хорошо.
Кроме того, даже если вы используете SafeHandle, вы должны утилизировать его, как если бы это был управляемый объект. В противном случае, если вы не утилизируете его вообще, ему придется ждать, пока GC не будет выпущен, и если вы сделаете его утилизировать в Dispose, но без финализатора, и никто не избавится от вас, тогда ему придется подождать до GC после того, который собрал вас.
b_richardson выше имеет правильный шаблон, это не сложно, и добавляя GC.SuppressFinalize (), вы избегаете двухпроходного GC, за исключением случаев, когда вы не утилизируете должным образом.
Что касается добавления логического значения для отслеживания, если мы уже были удалены, это будет работать, я предпочитаю просто написать свои методы Dispose для повторного запуска (проверка на нулевое значение и т. Д.), Также помогает сделать это таким образом когда объект может получить ресурсы во время использования, и вы хотите распоряжаться только теми, которые у него есть.