何时应使用Using语句?

8
很多人在SO上指出我应该更频繁地使用using语句。所以我正在练习。
问题是我无法确定什么时候使用它,什么时候不使用它。当我认为我应该使用它时,我会遇到像这个例子中的错误(PS. HashPhrase是我创建的一个类):
        using (HashPhrase hash = new HashPhrase())
        {
            connection.ConnectionString =
                "Provider=Microsoft.ACE.OLEDB.12.0;" +
                "Data Source=" + filePath + ";" +
                "Persist Security Info=False;" +
                "Jet OLEDB:Database Password=" + hash.ShortHash(pass) + ";";
        }

但是出现了错误:'Password_Manager.HashPhrase':类型在using语句中使用必须可以隐式转换为'System.IDisposable'

但在这个例子中,它能够正常工作:

    using (OleDbConnection connection = new OleDbConnection())
    {
        connection.ConnectionString =
            "Provider=Microsoft.ACE.OLEDB.12.0;" +
            "Data Source=" + filePath + ";" +
            "Persist Security Info=False;" +
            "Jet OLEDB:Database Password=" + hash.ShortHash(pass) + ";";

        using (OleDbCommand command = new OleDbCommand(sql, connection))
        {
            try
            {
                connection.Open();
                command.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message);
            }
        }
    }

有没有快速的准则来确定何时应该使用 using 语句?

5个回答

16

你的问题已经触及了答案。

如果类型实现了IDisposable接口,那么你应该尽可能使用using(也就是说,除非有强烈的理由不这样做,否则总是要使用)。

如果该类型没有实现IDisposable,那么你不能使用using,编译器会提示你,就像你已经发现的那样。


1
@downvoter:您是否可以解释一下您给出负评的原因? - LukeH

5

当类实现IDisposable接口时,应使用using语句。

这是一种简写方式,用于将对象包装在try-finally块中,以确保无论是否抛出异常,都始终调用对象的Dispose方法来释放任何资源。

要检查,请在Visual Studio中右键单击类名,然后选择转到声明以在对象浏览器中打开它。您可以轻松地检查类或其基类型是否实现了IDisposable。


4

In

using (var r = new R())
{
   // use r
}

R 应该实现 IDisposing 接口。


4

最简单的方法是查看对象是否实现了IDisposable接口。因此,请右键单击所需的对象/类,从下拉列表中选择“转到定义”(或按F12),然后查看该类是否实现了IDisposable接口。请注意,在实现多个接口/其他类的类中,您可能需要实际检查这些类是否也实现了IDisposable接口。


0
大多数情况下,我不会首先检查一个类是否实现了 IDisposable 接口(因为这可能被隐藏在基类中),如果我认为使用 Using 块有意义,我就编写它,如果无法编译,我就回滚到标准构造。懒惰?是的,有点。但它可以更快。
例如,VB:
Using oSerializer As XmlSerializer = New XmlSerializer(GetType(MyType))
    ...
End Using

例如,C#:

using (XmlSerializer serializer = new XmlSerializer(typeof(MyType)))
{
    ...
}

虽然我认为这应该是可能的,但上述两个片段都不会编译,因为XmlSerializer没有实现IDisposable(这让我有点奇怪,因为相关类如XmlReaderXmlWriter确实实现了IDisposable)。

那么你可以回到标准构造。

VB:

Dim oSerializer As XmlSerializer = New XmlSerializer(GetType(MyType))
...

C#:

XmlSerializer serializer = new XmlSerializer(typeof(MyType));
...

我完全同意在可用的情况下使用Using;它干净、简洁,而且您可以得到所承诺的处理和清理。太好了!


当有人投反对票却没有勇气说明原因时,这让我感到非常恼火。问题出在哪里? - SteveCinq

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