我在C#工作,并且我一直非常松懈地使用using
块来声明实现的对象IDisposable
,这显然是你应该做的.但是,我没有看到一种简单的方法来了解我何时滑倒.Visual Studio似乎没有以任何方式表明这一点(我只是错过了什么?).我每次申报任何东西时都应该检查帮助,然后逐渐建立一个百科全书式的记忆,对象是哪些,哪些不是一次性的?似乎没有必要,痛苦和容易出错.
如何你处理这个问题?
编辑:
看一下相关问题的侧边栏,我发现了另一个问题,它明确表示Dispose()
应该被对象的终结器调用.因此,即使你自己也没有自己调用它,它最终会发生,这意味着如果你不使用它就不会有内存泄漏using
(这是我认为我一直非常担心的).唯一需要注意的是,垃圾收集器不知道对象作为非托管内容持有多少额外内存,因此无法准确了解通过收集对象将释放多少内存.这将导致垃圾收集器的性能低于平常.
简而言之,如果我错过了,那就不是世界末日了using
.我只是希望有些东西会产生至少一个警告.
(偏离主题:为什么链接到另一个问题没有特殊的降价?)
编辑:
好的,好的,别叫吵了.这是超级决斗所有激烈的戏剧性 - 花栗鼠级别的重要打电话Dispose()
或我们都会死.
现在.鉴于此,为什么这么容易 - 地狱,为什么甚至允许 - 做错了?你必须尽力去做正确的事.像其他一切一样做它会导致世界末日(显然).封装这么多,是吧?
[偷偷摸摸,反感]
FxCop 可能有所帮助(虽然它没有发现我刚刚开始的测试); 但是是的:你打算检查一下.IDisposable
这是你需要养成这种习惯的系统中非常重要的一部分.使用intellisense寻找.D
是一个好的开始(虽然不完美).
但是,不需要花费很长时间就能熟悉需要处理的类型; 通常涉及任何外部的东西(连接,文件,数据库),例如.
ReSharper也做了这项工作,提供了"投入使用构造"选项.尽管如此......它不会将其视为错误
当然,如果你不确定 - 尝试 using
一下:如果你是偏执狂,编译器会嘲笑你:
using (int i = 5) {} Error 1 'int': type used in a using statement must be implicitly convertible to 'System.IDisposable'
如果一个对象实现了IDisposable
接口,那么它是有原因的,你打算调用它,它不应该被视为可选的.最简单的方法是使用using
块.
Dispose()
不仅仅是由对象的终结器调用,事实上,许多对象将实现Dispose()
但没有终结器(这是完全有效的).
处置模式背后的整个想法是,您提供了一种有点确定性的方法来释放由对象(或其继承链中的任何对象)维护的非托管资源.如果没有Dispose()
正确调用,您绝对可能会遇到内存泄漏(或任何其他问题).
该Dispose()
方法与析构函数无任何关系.你在.NET中最接近析构函数的是终结器.using语句不进行任何释放...事实上,调用Dispose()
不会在托管堆上进行任何释放; 它只释放已分配的非托管资源.在GC运行并收集分配给该对象图的内存空间之前,托管资源不会被真正释放.
确定类是否实现的最佳方法IDisposable
是:
IntelliSense(如果它有一个Dispose()
或一个Close()
方法)
MSDN
反光
编译器(如果它没有实现IDisposable
你得到编译器错误)
常识(如果感觉你应该在完成之后关闭/释放对象,那么你可能应该这样做)
语义(如果有的话Open()
,可能会有一个相应的Close()
应该被调用)
编译器.尝试将其放入using
声明中.如果它没有实现IDisposable,编译器将生成错误.
将dispose模式视为范围生命周期管理.您希望尽可能快地获取资源,尽可能快地使用,并尽快发布.using语句通过确保Dispose()
即使存在异常也将进行调用来帮助实现此目的.