C#中“using”的用途是什么?

356

用户kokos通过提到using关键字回答了精彩的问题《C#的隐藏特性》。你能详细说明一下吗?using有哪些用途?


这是支持RAII习惯的C#方式:http://www.hackcraft.net/raii/ - Nemanja Trifunovic
1
您可以使用已实现IDispose接口的对象。当该对象超出范围时,Using语句将调用Dispose方法。它保证即使发生任何异常也会调用Dispose。它的工作方式类似于finally子句并执行Dispose。 - CharithJ
29个回答

4
有趣的是,您也可以将 using/IDisposable 模式用于其他有趣的事情(例如 Rhino Mocks 使用它的另一点)。基本上,您可以利用编译器将始终在“使用”对象上调用 .Dispose 的事实。如果您需要在某个操作之后发生某些事情...即具有明确定义的开始和结束...那么您只需创建一个 IDisposable 类,在构造函数中启动操作,然后在 Dispose 方法中完成即可。
这使您可以使用非常好的 using 语法来表示所述操作的显式开始和结束。这也是 System.Transactions 的工作原理。

3
public class ClassA:IDisposable
{
    #region IDisposable Members
    public void Dispose()
    {
        GC.SuppressFinalize(this);
    }
    #endregion
}

public void fn_Data()
{
    using (ClassA ObjectName = new ClassA())
    {
        // Use objectName
    }
}

需要解释一下。例如,什么是想法/主旨?请通过编辑(更改)您的答案来回复,而不是在评论中回复(不要包含“编辑:”,“更新:”或类似内容 - 答案应该看起来像今天写的)。 - Peter Mortensen

3
在C#中,using关键字有两种用法,具体如下。
  1. As a directive

    Generally we use the using keyword to add namespaces in code-behind and class files. Then it makes available all the classes, interfaces and abstract classes and their methods and properties in the current page.

    Example:

    using System.IO;
    
  2. As a statement

    This is another way to use the using keyword in C#. It plays a vital role in improving performance in garbage collection.

    The using statement ensures that Dispose() is called even if an exception occurs when you are creating objects and calling methods, properties and so on. Dispose() is a method that is present in the IDisposable interface that helps to implement custom garbage collection. In other words if I am doing some database operation (Insert, Update, Delete) but somehow an exception occurs then here the using statement closes the connection automatically. No need to call the connection Close() method explicitly.

    Another important factor is that it helps in Connection Pooling. Connection Pooling in .NET helps to eliminate the closing of a database connection multiple times. It sends the connection object to a pool for future use (next database call). The next time a database connection is called from your application the connection pool fetches the objects available in the pool. So it helps to improve the performance of the application. So when we use the using statement the controller sends the object to the connection pool automatically, there is no need to call the Close() and Dispose() methods explicitly.

    You can do the same as what the using statement is doing by using try-catch block and call the Dispose() inside the finally block explicitly. But the using statement does the calls automatically to make the code cleaner and more elegant. Within the using block, the object is read-only and cannot be modified or reassigned.

    Example:

    string connString = "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;";
    
    using (SqlConnection conn = new SqlConnection(connString))
    {
          SqlCommand cmd = conn.CreateCommand();
          cmd.CommandText = "SELECT CustomerId, CompanyName FROM Customers";
          conn.Open();
          using (SqlDataReader dr = cmd.ExecuteReader())
          {
             while (dr.Read())
             Console.WriteLine("{0}\t{1}", dr.GetString(0), dr.GetString(1));
          }
    }
    
在上述代码中,我没有关闭任何连接;它将自动关闭。由于使用了using语句(如using (SqlConnection conn = new SqlConnection(connString))和SqlDataReader对象也是如此,因此using语句将自动调用conn.Close()方法,并且如果发生任何异常,它也会自动关闭连接。

有关更多信息,请参见使用和重要性在C#中的Using


3

使用ADO.NET时,您可以使用关键字来定义连接对象或读取器对象等。这样在代码块完成后,它将自动释放您的连接。


2
我只想补充一点,代码块甚至不必完成。使用块将在未处理的异常情况下处理资源。 - harpo
只是为了进一步澄清,这是一种确保垃圾收集器在您想要时处理分配的方式,而不是在它想要时处理。 - moswald

3

链接已经失效: "嗯,我们无法找到该网站。我们无法连接到www.davidarno.org上的服务器。" - Peter Mortensen

3
总之,当您使用实现了IDisposable接口的局部变量时, 一定 要使用using1,没有例外。
如果您使用非本地的IDisposable变量,则始终要实现IDisposable模式
两个简单的规则,没有例外1。否则,防止资源泄漏将是一件真正令人头痛的事情。

1):唯一的例外是——当您处理异常时。此时在finally块中显式调用Dispose可能会少些代码。


2

using关键字用于在使用资源后自动释放资源。

例如,如果您分配了一个文件资源,并且只需要在代码的一部分进行一些读写操作,那么使用 using 可以帮助您立即释放该文件资源。

被使用的资源需要实现 IDisposable 接口才能正常工作。

示例:

using (File file = new File (parameters))
{
    // Code to do stuff with the file
}

1

using关键字定义对象的范围,当范围完成后处理该对象。例如:

using (Font font2 = new Font("Arial", 10.0f))
{
    // Use font2
}

请点击此处查看有关C# using 关键字的MSDN文章。


链接已经失效: "Visual Studio 2005 已退役文档" - Peter Mortensen

1

另一个合理使用的例子是立即处理对象:

using (IDataReader myReader = DataFunctions.ExecuteReader(CommandType.Text, sql.ToString(), dp.Parameters, myConnectionString)) 
{
    while (myReader.Read()) 
    {
        MyObject theObject = new MyObject();
        theObject.PublicProperty = myReader.GetString(0);
        myCollection.Add(theObject);
    }
}

1
对我来说,“using”这个名称有点令人困惑,因为它既可以是导入命名空间的指令,也可以是错误处理语句(就像本文所讨论的那样)。
一个不同的名称用于错误处理会更好,并且可能更加明显。

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