Часто встречаюсь с практикой когда, программисты перекладывают бремя освобождения ресурсов на плечи среды исполнения .Net CLR
Рассуждения выглядят следующим образом, если код управляемый, то я не должен беспокоиться об освобождении памяти и других ресурсов.

К сожалению это не совсем так, отсутствие принудительного освобождения ресурсов может приводить в излишней нагрузки и не рациональному использованию ресурсов. Более того, в некоторых сценариях это может приводить к непредвиденным последствиям.

Для избежания проблем с вашим кодом, заведите себе правило, если используемый объект реализует интерфейс IDisposable, то сразу по завершении использования этого объекта вызывайте метод Dispose. Это гарантирует освобождение ресурсов используемых объектом, снимет и лишнею нагрузку со сборщика мусора.

Если вы используете такой объект в рамках одного метода, то можно использовать инструкцию using() которая гарантированно освободит ресурсы, вне зависимости от того, что произойдет в процессе исполнения.

Код:
public string GetFileContent(string filename)
{
  using(var reader = new StreamReader())
  {
    return reader.ReadToEnd();
  }
}