﻿# V3114\. IDisposable object is not disposed before method returns\.

Чтобы понять смысл данной диагностики, давайте для начала немного вспомним теорию\.

Сборщик мусора автоматически освобождает память, связанную с контролируемым объектом, если он больше не используется и на него не осталось видимых ссылок\. Тем не менее, невозможно предсказать, когда именно произойдёт сборка мусора \(если не вызывать её вручную\)\. Кроме того, сборщик мусора не имеет информации о таких неуправляемых ресурсах, как дескрипторы, окна или открытые файлы и потоки\. Метод 'Dispose' обычно используется, чтобы освобождать такие неуправляемые ресурсы\. 

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

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

Рассмотрим пример такой ситуации:

```cpp
string Foo()
{
  var stream = new StreamReader(@"С:\temp.txt");
  return stream.ReadToEnd();
}
```

В данном случае объект 'StreamReader' будет хранить в себе дескриптор открытого файла даже после выхода из метода 'Foo', тем самым блокируя его для других программ и операционной системы до тех пор, пока сборщик мусора не очистит его\.

Чтобы избежать этого \- своевременно освобождайте ресурсы, используя метод 'Dispose' как в примере ниже:

```cpp
string Foo()
{
  var stream = new StreamReader(@"С:\temp.txt");
  var result = stream.ReadToEnd();

  stream.Dispose();
  return result;
}
```

Однако, для более надёжного освобождения ресурсов рекомендуется использовать конструкцию 'using'\. Она обеспечит автоматическую очистку ресурсов используемого объекта после завершения:

```cpp
string Foo()
{
  using (var stream = new StreamReader(@"С:\temp.txt"))
  {
    return stream.ReadToEnd();
  }
}
```

Компилятор раскроет блок 'using' в блок 'try finally', и в 'finally' вставит вызов метода 'Dispose' \- это гарантирует очистку объекта даже в случае возникновения исключений\.