Вызовы через интерфейс всегда виртуальные, независимо от того, будет ли «обычный» вызов прямым или виртуальным.Если метод, который фактически выполняет работу по утилизации, не является виртуальным, за исключением случаев, когда он вызывается через интерфейс, тогда всякий раз, когда класс захочет избавиться от него, он должен будет убедиться, что он сам ссылается на iDisposable и вызывает его.*
В коде шаблона ожидается, что не виртуальная функция Dispose всегда будет одинаковой в родительском и дочернем элементах [просто вызывая Dispose (True)], поэтому никогда не нужно ее переопределять.Вся работа выполняется в виртуальном Dispose (Boolean).
Честно говоря, я думаю, что использование шаблона Dispose немного глупо в тех случаях, когда нет оснований ожидать, что классы-потомки будут напрямую хранить неуправляемые ресурсы.В первые дни .net классам часто требовалось напрямую хранить неуправляемые ресурсы, но сегодня в большинстве ситуаций я вижу нулевые потери от простой реализации Dispose () напрямую.Если будущему классу-потомку необходимо использовать неуправляемые ресурсы, он может и обычно должен заключать эти ресурсы в свои собственные объекты Finalizable.
С другой стороны, для некоторых видов методов могут быть преимущества наличия неВиртуальный метод базового класса, задача которого состоит в том, чтобы связать его с защищенным виртуальным методом и заставить виртуальный метод вызываться Dispose(bool)
на самом деле не хуже, чем VirtDispose()
, даже если предоставленный аргумент довольно бесполезен.Например, в некоторых ситуациях может быть необходимо, чтобы все операции над объектом были защищены блокировкой, которой владеет объект базового класса.Если не виртуальный базовый класс Dispose
получит блокировку перед вызовом виртуального метода, это избавит все базовые классы от необходимости беспокоиться о самой блокировке.