Есть ли список общих объектов, которые реализуют IDisposable для оператора using?

Мне было интересно, есть ли какая-то шпаргалка, для которой объекты хорошо сочетаются с оператором использования... SQLConnection, MemoryStream и т. д.

Сделав еще один шаг вперед, было бы здорово даже показать другие «кусочки головоломки», например, как вы должны на самом деле вызывать connection.Close() перед закрытием с помощью операторной скобки.

Что-то подобное существует? Если нет, может быть, мы должны сделать один.


person John B    schedule 23.06.2009    source источник
comment
Зачем вам нужно вызывать connection.Close() перед концевой скобкой? Я не знаю, есть ли много других кусочков головоломки.   -  person John Saunders    schedule 23.06.2009
comment
Почему список? Вы можете легко проверить, реализует ли объект IDisposable.   -  person Groo    schedule 23.06.2009
comment
@Groo: вам действительно нужно проверить документы, некоторые типы скрывают Dispose(). Так что не так просто.   -  person Henk Holterman    schedule 23.06.2009
comment
@John Saunders: Вы уверены, что не должны закрывать SQL-соединение?   -  person John B    schedule 28.07.2009
comment
@John Saunders: Пусть люди решают: stackoverflow.com/questions/1195829/   -  person John B    schedule 28.07.2009


Ответы (9)


В Microsoft FxCop есть правило, проверяющее использование IDisposbale в блоке using.

person Dmitry Risenberg    schedule 23.06.2009

Взгляните на мой пост об этом на http://www.lancemay.com/2010/01/idisposable-cheat-sheet/. Не уверен, что это то, что вы ищете, но, исходя из исходного вопроса, похоже, что это может быть.

person Lance    schedule 29.04.2010
comment
Прохладный! Это именно то, что я изначально искал! - person John B; 29.04.2010
comment
вау, столько комментариев, а это ответ! спасибо Ланс! - person aron; 16.03.2012
comment
Ссылка не работает! - person CFreitas; 06.11.2020

Следующий метод C# выводит список всех типов IDisposable, найденных в определенной сборке. (Используемые пространства имен: System, System.Collections.Generic, System.IO, System.Reflection)

  static void PrintDisposableTypesFromFile(String path)
  {
     Assembly assembly = Assembly.LoadFrom(path);
     foreach (Type type in assembly.GetTypes())
        if (type.GetInterface("IDisposable") != null)
           Console.WriteLine(type.FullName);
  }

Следующий метод С# использует предыдущий, чтобы сделать то же самое для всех сборок в каталоге и его подкаталогах, например. "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727":

  static void PrintDisposableTypesFromDirectory(DirectoryInfo dir, bool warn)
  {
     foreach (FileInfo file in dir.GetFiles("*.dll"))
     {
        try
        {
           PrintDisposableTypesFromFile(file.FullName);
        }
        catch (Exception ex)
        {
           if (warn)
           {
              Console.Error.WriteLine(
                 String.Format(
                    "WARNING: Skipped {0}: {1}",
                    new object[] { file.FullName, ex.Message }));
           }
        }
     }
     // recurse
     foreach (DirectoryInfo subdir in dir.GetDirectories())
        PrintDisposableTypesFromDirectory(subdir, warn);

  }

Я не уверен, что список всех одноразовых материалов очень полезен, но я использовал аналогичный код, чтобы найти другие интересные вещи, такие как полный список текстовых кодировок, поддерживаемых платформой .NET.

person Wim Coenen    schedule 24.06.2009
comment
+1 за усилия, но я думаю, что было бы проще просто использовать отражатель :) - person John B; 31.12.2009

Если вы не уверены, реализует ли класс IDisposable или нет, все равно заключите его в блок using. Если вы получите ошибку компиляции, просто удалите ее. Вы потеряете всего несколько секунд, печатая текст.

person Christian Hayter    schedule 23.06.2009
comment
В большинстве случаев, если есть метод Dispose, он будет реализовывать IDisposable. - person weiqure; 23.06.2009
comment
@weiqure - но не наоборот - person Henk Holterman; 23.06.2009
comment
Всегда наоборот, поскольку нет класса, реализующего IDisposable, без метода Dispose. И я еще не видел класса, который имеет метод Dispose, но не реализует IDisposable. - person weiqure; 24.06.2009

В дополнение к другим ответам обратите внимание, что класс может реализовывать IDisposable, но не иметь Dispose в списке IntelliSense.

class MyClass :IDisposable
{
    void IDisposable.Dispose()
    {
        /* Stuff */
    }
}
person billpg    schedule 09.07.2009

Если вы используете Visual Studio, вы можете нажать F12 в объявлении типа, и вы попадете на экран метаданных или определение класса (если у вас есть исходный код). Если у вас разные сочетания клавиш, щелкните правой кнопкой мыши и «перейдите к определению». Оттуда вы можете увидеть, что реализует класс. Я предлагаю сделать это для всех классов в первый раз, когда вы сталкиваетесь с ними, чтобы «почувствовать», на что способен класс.

person Kleinux    schedule 09.07.2009
comment
Да, но не каждый класс, который реализует IDisposable, реализует его напрямую. Возьмем, к примеру, DataTable (который, кстати, вам не нужно удалять... но это другой разговор stackoverflow.com/questions/913228/) - person Grinn; 15.06.2010

Простой способ получить список типов, реализующих IDisposable, — открыть Reflector, перейти к System.IDisposable, развернуть узел, а затем развернуть узел «Производные типы».

Чтобы убедиться, что ваш список полный, убедитесь, что все сборки, которые вы используете, были «открыты» в Reflector.

person Kevin Pullin    schedule 23.06.2009

С ReSharper вы можете показать все производные типы. Может быть, вы можете сделать это с помощью браузера объектов и без ReSharper. Перейдите к определению интерфейса и найдите «показать наследников».

person tanascius    schedule 23.06.2009
comment
Не зная ReSharper, он работает для интерфейсов? И это для всего проекта, или вы могли бы включить GAC и другие папки? - person Henk Holterman; 23.06.2009
comment
Он работает для всего и может включать библиотечные сборки, в том числе в GAC. Вы также можете щелкнуть назначение, и оно предложит использовать блок, если назначаемый тип реализует IDisposable. - person John Saunders; 23.06.2009

Быстрый и грязный способ проверить, реализует ли тип IDisposable, состоит в том, чтобы создать его экземпляр и проверить, есть ли у экземпляра функция-член Dispose(). Если это так, вы можете быть на 99% уверены, что он реализует IDisposable.

person Rune Grimstad    schedule 24.06.2009