在C#中使用using语句

4

1
你在 Stack Overflow 这里做过搜索吗? - Dave Van den Eynde
1
https://dev59.com/pHVC5IYBdhLWcg3wsTVi - Daniel Earwicker
1
它工作正常。我在SO的搜索框中输入了“C# using”,它返回了一堆相关的回复。第四个回复是@cgreeno复制并粘贴的相同答案。 - TFD
1
@TFD:哥们,那太糟糕了。难道没有相应的徽章吗?“你因为为另一个用户的答案获得声望而获得了‘忍者’徽章”。;-) - Zano
@Michael Kniskern,我没有“复制粘贴”任何东西,您可以用多少种不同的方式实现using语句或者展示它与try finally相同呢? - cgreeno
显示剩余4条评论
6个回答

41

using 语法可以(应该)用作为实现 IDisposable 接口的任何对象定义一个范围的方法。使用 using 语句可以确保在发生异常时调用 Dispose 方法。

    //the compiler will create a local variable 
    //which will go out of scope outside this context 
    using (FileStream fs = new FileStream(file, FileMode.Open))
    {
         //do stuff
    }

或者你可以直接使用:

    FileStream fs;
    try{
       fs = new FileStream();
       //do Stuff
    }
    finally{
        if(fs!=null)
           fs.Dispose();
    }

MSDN的额外阅读材料

C#通过.NET Framework共同语言运行时(CLR)自动释放不再需要的对象所使用的内存。内存的释放是非确定性的;CLR决定执行垃圾收集时才会释放内存。然而,最好尽快释放有限资源,如文件句柄和网络连接。

using语句允许程序员指定使用资源的对象何时应该释放它们。提供给using语句的对象必须实现IDisposable接口。该接口提供了Dispose方法,该方法应释放对象的资源。


4
+1 - 很好的回答 - 需要注意的是编译器实际上会用 try/finally 语句来替换 using 语句。 - Andrew Hare

3

使用 using(){} 语法糖可以确保任何具有 IDisposable 接口的对象例如 SqlConnection, 在 using(){} 作用域之外被正确释放。

using(SqlConnection conn = new SqlConnection(connString))
{
  //use connection
}

//shorter than

SqlConnection conn = new SqlConnection(connString)
try
{
  //use connection 
}
finally
{
    conn.Dispose();
}

3

当打开流或数据库连接时,通常会使用它。

它的行为类似于 try { ... } finally { ... } 块。在 using 块之后,用括号实例化的 IDisposable 对象将被正确关闭。

using (Stream stream = new Stream(...))
{


}

使用这个示例,在块结束后,流将被正确关闭。

2

这种使用方式与释放资源有关,只能与实现IDisposable接口的类结合使用。

示例:

using(SqlConnection conn = new SqlConnection(someConnectionString))
{
     //Do some database stuff here
}

在使用块结束时,即使在块内抛出异常,也会调用conn.Dispose。对于SwqlConnection对象,这意味着连接始终关闭。
这种结构的缺点是现在无法知道发生了什么。
希望这可以回答您的问题?

2
无论何时您的代码创建一个实现IDisposable接口的对象,您的代码都应该在using块内进行创建,就像上面所示。
但是有一个例外。WCF代理类设计中的错误阻止了using语句对代理类的有用性。简而言之,代理类上的Dispose方法可能会抛出异常。WCF团队认为没有理由不允许这种情况发生。
不幸的是,没有看到原因并不意味着没有原因。
try
{
    using (var svc = new ServiceReference.ServiceName())
    {
        throw new Exception("Testing");
    }
}
catch (Exception ex)
{
    // What exception is caught here?
}

如果隐式的Dispose调用抛出异常,那么catch块会捕获该异常,而不是在using块内抛出的异常。


2
使用using语句可以确保对象在不再需要时被正确地处理。它基本上避免了编写obj.Dispose();代码,并提供了有关变量范围和用法的视觉指南。
请参阅MSDN页面以获取更多信息。

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