有没有一个常见对象的列表,它实现了IDisposable接口,可以在using语句中使用?

16

我想知道是否有一种作弊表,可以告诉我哪些对象最适合与 using 语句一起使用... SQLConnectionMemoryStream 等等。

更进一步,甚至展示其他"谜题的部分",例如在关闭 using 语句括号之前应该如何调用 connection.Close()

有这样的东西吗? 如果没有,也许我们应该制作一个。


为什么需要在结束括号之前调用connection.Close()?我不知道还有其他需要注意的要点。 - John Saunders
为什么要使用列表?因为你可以轻松地检查一个对象是否实现了IDisposable接口。 - vgru
@Groo:你真的得查一下文档,有些类型会隐藏Dispose()方法,所以不是那么容易的事情。 - H H
@John Saunders: 你确定不应该关闭SQL连接吗? - John B
@John Saunders:让人民决定:https://dev59.com/NHM_5IYBdhLWcg3w2XPw - John B
9个回答

14

2
太棒了!这正是我最初要寻找的东西! - John B
哇,有这么多的评论,这就是答案!谢谢Lance! - aron
2
链接已损坏! - CFreitas
可以通过互联网档案馆查看Lance的帖子 链接 - nwsmith
应该发表一个真正的答案,而不是一个自我服务的链接来增加自己的广告收入。 - Bill Tarbell
@BillTarbell,哇,老兄;12年过去了,你还是如此热情。o.0 另外,即使在那时候,我也没有收入。我发布它是因为它很相关,我写了它,并且它仍然是排名第一的答案... - Lance

10

Microsoft FxCop有一条规则,检查你是否在using块中使用了IDisposable接口。


7
以下是一个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#方法利用前面的方法来处理目录及其子目录中的所有程序集,例如"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框架支持的完整文本编码列表。


+1 鼓励你的努力,但我认为直接使用反射会更容易 :) - John B

4

如果你不确定一个类是否实现了IDisposable接口,无论如何都要将其包含在using代码块中。如果出现编译错误,只需将其删除即可。这样做只会浪费你几秒钟的打字时间。


1
在大多数情况下,如果存在Dispose方法,则它将实现IDisposable接口。 - weiqure
@weiqure - 但不反过来 - H H
始终如此,因为没有实现Dispose方法的IDisposable实现类。我还没有看到有一个实现了Dispose方法但没有实现IDisposable接口的类。 - weiqure

3
除了其他答案之外,需要注意的是一个类可能会实现IDisposable接口但在智能感知列表中不会出现Dispose方法。
class MyClass :IDisposable
{
    void IDisposable.Dispose()
    {
        /* Stuff */
    }
}

3
如果您使用的是Visual Studio,您可以按下F12键来查看元数据或类定义(如果您有源代码)。如果您的按键绑定不同,请右键单击并选择“转到定义”。从那里,您可以看到一个类实现了什么。我建议您在第一次遇到所有类时都这样做,以了解该类的功能。

2
是的,但并非每个实现IDisposable接口的类都直接实现它。以DataTable为例(顺便说一句,您不需要Dispose它...但那是另一个话题https://dev59.com/XnNA5IYBdhLWcg3wjOve.) - Grinn

2
一个获取所有实现了IDisposable接口的类列表的简单方法是打开Reflector,找到,展开节点并扩展“派生类型”节点。
要确保您的列表是完整的,请验证您正在使用的所有程序集是否在Reflector中已经“打开”。

1
使用 ReSharper,您可以显示所有派生类型。也许您可以在没有 ReSharper 的情况下使用对象浏览器来完成此操作。转到接口定义并查找“显示继承者”。

不知道ReSharper,它能用于接口吗?它是项目范围的还是可以包括GAC和其他文件夹? - H H
它适用于所有内容,可以包括库程序集,包括GAC中的程序集。如果被分配的类型实现了IDisposable,则还可以单击分配并建议使用块。 - John Saunders

0
一种快速而不太严谨的检查类型是否实现IDisposable的方法是创建一个实例并检查该实例是否具有Dispose()成员函数。如果有,那么您可以99%确定它实现了IDisposable。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接