当前位置:  开发笔记 > 编程语言 > 正文

我什么时候应该在C#中使用"使用"块?

如何解决《我什么时候应该在C#中使用"使用"块?》经验,为你挑选了4个好方法。

是否存在我应该(或不应该?)使用"使用"块的特定情况:

using(SomeType t = new SomeType()){
    ...
}

Scott Langha.. 92

完成后,某些对象需要采取一些操作.通常这是因为对象使用某种需要处理的资源.例如,如果您具有类File的文件对象,并且此对象从文件系统打开文件,则需要再次关闭文件系统中的文件.

如果您刚刚离开文件对象,并且忘记调用file.Close(),那么在垃圾收集器(GC)运行并且没有任何东西仍在使用文件对象之前,它将不会被清除.当垃圾收集器运行时应留给公共语言运行时(CLR)来决定.如果在完成文件后GC没有运行很长时间,则文件可能会长时间保持打开状态.如果有许多文件对象,或者某些东西想要打开文件,这可能会造成很大的问题,但是因为你离开的文件对象仍然存在,所以不能.

为了解决这个问题,C#具有IDisposable接口.这有一个名为Dispose的方法.需要一些清理的类实现此Dispose方法.这为清理任何使用资源的对象提供了标准方法.有许多类需要调用Dispose.这个问题是代码被Dispose调用覆盖,并且它们很难跟随,因为你新建对象并调用Dispose来清理它的地方是不同的.因此,您必须仔细查看代码并非常小心地检查是否在正确的位置调用了Dispose.

为了解决这个问题,C#引入了'using'关键字.您可以在新对象的位置放置一个"using"关键字,这样可以确保为您调用Dispose.它保证无论发生什么事都会调用Dispose ...即使在using语句的主体内抛出了异常.

因此,当您想要确保分配资源的对象将被清理时,您应该使用'using'.


using只能用于在堆栈中声明的对象,即在函数中.它不适用于声明为类成员的对象.对他们来说,你必须打电话给自己.您可能必须在类中实现Dispose,以便in可以调用它所需的任何成员对象上的Dispose.


需要使用它们的公共对象是:文件,数据库连接,图形对象,如笔和画笔.


有时,当您希望两个操作一起发生时,也会使用它.例如,如果您想在输入代码块时写入日志语句,并且在退出时您可以编写一个可以使用的日志类,如下所示:

using( Log log = new Log("Doing stuff") )
{
    // Stuff
}

可以使用日志类的构造函数来写出消息,并且Dispose方法也可以将其写出来.实现终结器(~Log)以断言是否调用Dispose方法以确保在'new Log'周围记住'using'.



1> Scott Langha..:

完成后,某些对象需要采取一些操作.通常这是因为对象使用某种需要处理的资源.例如,如果您具有类File的文件对象,并且此对象从文件系统打开文件,则需要再次关闭文件系统中的文件.

如果您刚刚离开文件对象,并且忘记调用file.Close(),那么在垃圾收集器(GC)运行并且没有任何东西仍在使用文件对象之前,它将不会被清除.当垃圾收集器运行时应留给公共语言运行时(CLR)来决定.如果在完成文件后GC没有运行很长时间,则文件可能会长时间保持打开状态.如果有许多文件对象,或者某些东西想要打开文件,这可能会造成很大的问题,但是因为你离开的文件对象仍然存在,所以不能.

为了解决这个问题,C#具有IDisposable接口.这有一个名为Dispose的方法.需要一些清理的类实现此Dispose方法.这为清理任何使用资源的对象提供了标准方法.有许多类需要调用Dispose.这个问题是代码被Dispose调用覆盖,并且它们很难跟随,因为你新建对象并调用Dispose来清理它的地方是不同的.因此,您必须仔细查看代码并非常小心地检查是否在正确的位置调用了Dispose.

为了解决这个问题,C#引入了'using'关键字.您可以在新对象的位置放置一个"using"关键字,这样可以确保为您调用Dispose.它保证无论发生什么事都会调用Dispose ...即使在using语句的主体内抛出了异常.

因此,当您想要确保分配资源的对象将被清理时,您应该使用'using'.


using只能用于在堆栈中声明的对象,即在函数中.它不适用于声明为类成员的对象.对他们来说,你必须打电话给自己.您可能必须在类中实现Dispose,以便in可以调用它所需的任何成员对象上的Dispose.


需要使用它们的公共对象是:文件,数据库连接,图形对象,如笔和画笔.


有时,当您希望两个操作一起发生时,也会使用它.例如,如果您想在输入代码块时写入日志语句,并且在退出时您可以编写一个可以使用的日志类,如下所示:

using( Log log = new Log("Doing stuff") )
{
    // Stuff
}

可以使用日志类的构造函数来写出消息,并且Dispose方法也可以将其写出来.实现终结器(~Log)以断言是否调用Dispose方法以确保在'new Log'周围记住'using'.


总结!+1

2> Otávio Décio..:

SomeType类实现时IDisposable.


using得到翻译为:SomeType t = new SomeType(); 尝试{...} finally {t.Dispose(); }
@Matthew事实证明是的 - 特别是在你处理WCF代理时.一些问题可以在这里找到 - http://msdn.microsoft.com/en-us/library/aa355056.aspx
在某种情况下你不应该*使用`using`模式来实现`IDisposable`的类型吗?
@Matthew在将"using"与任何异步关联时需要谨慎行事:http://softwareblog.alcedo.com/post/2011/12/09/Using-blocks-and-asynchronous-operations.aspx

3> bdukes..:

using在类型实现时使用IDisposable,除非你打算将它包装在try/catch block中,然后你也可以(根据你喜欢的外观)使用一个finally块.



4> Joel Coehoor..:

我看到很多其他的答案时表示你应该有一个using说法.我想解决的时候,特意应该不会有一个using说法:

如果需要在当前函数范围之外使用对象,请不要使用using块.很好的例子是返回数据库连接的工厂方法或需要返回datareader的方法.在任何一种情况下,如果使用using语句创建对象,它将在返回方法之前处理,因此不能在方法之外使用.

现在,您仍然希望确保处理这些对象,因此您仍然可能需要在using某处使用语句.只是不要将它包含在实际创建对象的方法中.相反,您可以将函数调用本身包装在using语句中.

推荐阅读
云聪京初瑞子_617
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有