TL; DR:
Если вам нужно высвободить неуправляемых ресурсов - сценарий, в котором мы будем использовать IDisposable
, тогда реализуем IDisposable
и нене делайте класс синглтоном.
Если у вас нет неуправляемых ресурсов, а синглтон - это то, что вам нужно, сделайте его синглтоном и не беспокойтесь о «установщике», который установит нулевые значения.В этом нет необходимости.
Вы пытаетесь сделать две вещи: сделать класс одноразовым и сделать его синглтоном, и вы увидели, что они не подходят друг другу.Вместо того, чтобы игнорировать IDisposable
и искать другой способ освобождения управляемых ресурсов, я бы поступил наоборот.Реализуйте IDisposable
, но не делайте класс одиночным.
Почему?Прежде всего потому, что обычно существуют другие способы обеспечить существование только одного экземпляра класса, не делая его одиночным.Например, большинство контейнеров внедрения зависимостей, включая IServiceProvider
, упрощают регистрацию зависимости как синглтона:
services.AddSingleton<ThingThatIOnlyWantOneOf>();
Это не означает, что ThingThatIOnlyWantOneOf
на самом деле является синглтоном.Мы могли бы создать несколько экземпляров этого.Мы просто указываем, что мы хотим создать только один экземпляр и использовать его снова и снова.
Даже если мы не используем какой-либо контейнер IoC / DI, мы все равно можем ограничить количество экземпляров классамы создаем, фактически не делая это единственным.(И это дает нам возможность изменить свое мнение, если / когда мы поймем, что нам нужно больше экземпляров.)
Теперь проблема в том, как написать класс в виде синглтона и makeкласс одноразовых исчез.Мы используем разные средства для создания и повторного использования одного экземпляра класса, и этот класс может быть одноразовым.
Стоит также отметить, что установка чего-либо в null - это не то же самое, чтореализация IDisposable
.
Как правило, мы не устанавливаем нулевые ссылки на объекты, когда закончим с ними, потому что .NET Framework справляется с этим за нас.Объект выходит из области видимости, когда на него больше нет ссылок, а затем сборщик мусора удаляет его из памяти.Все это происходит эффективно, и мы ничего не делаем.Вот почему вы не видите лишних строк кода в конце методов, чтобы установить объекты в null.
Мы реализуем IDisposable
только когда класс имеет дело с неуправляемыми ресурсами - например, соединениями SQL или открытым файломпотоки.Эти классы должны сделать что-то, чтобы высвободить свои ресурсы, и мы хотим, чтобы это произошло как можно скорее.
Это означает, что если что-то сделал должно быть одноразовым, то простоустановка его в ноль не сделает этого.Мы бы хотели на самом деле позвонить Dispose()
.Если на самом деле он не должен быть одноразовым, нам все равно не нужно устанавливать его в null.Мы можем просто позволить ему выйти из области видимости и собрать мусор.
Так что, если вы обеспокоены тем, что вам нужно что-то «очистить» или установить что-либо на ноль, вы, вероятно, этого не сделаете.IDisposable
существует для обозначения вещей, которые необходимо «очистить».Это способ узнать, что если что-то не не реализует это, нам не нужно об этом беспокоиться.(В противном случае мы бы установили все на ноль только из-за сомнений и неопределенности, и это не было бы так весело.)