foreach会自动调用Dispose吗?
在 C# 中,foreach 是否会自动对任何实现 IDisposable 的对象调用 Dispose?
http://msdn.microsoft.com/en- us/library/aa664754(v=vs.71).aspx 似乎表明确实如此:
*否则,集合表达式是实现 System.IEnumerable 的类型,并且 foreach 语句的扩展为: 复制
IEnumerator enumerator =
((System.Collections.IEnumerable)(collection)).GetEnumerator();
try {
while (enumerator.MoveNext()) {
ElementType element = (ElementType)enumerator.Current;
statement;
}
}
finally {
IDisposable disposable = enumerator as System.IDisposable;
if (disposable != null) disposable.Dispose();
}
In C#, Does foreach automatically call Dispose on any object implementing IDisposable?
http://msdn.microsoft.com/en-us/library/aa664754(v=vs.71).aspx seems to indicate that it does:
*Otherwise, the collection expression is of a type that implements System.IEnumerable, and the expansion of the foreach statement is:
Copy
IEnumerator enumerator =
((System.Collections.IEnumerable)(collection)).GetEnumerator();
try {
while (enumerator.MoveNext()) {
ElementType element = (ElementType)enumerator.Current;
statement;
}
}
finally {
IDisposable disposable = enumerator as System.IDisposable;
if (disposable != null) disposable.Dispose();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,如果 foreach 实现了 IDisposable,它将在枚举器上调用 Dispose()。
Yes, foreach will call Dispose() on the enumerator if it implements IDisposable.
这个问题/答案措辞不好。
目前尚不清楚所提出的问题是否是:
问:“foreach 在移动到下一个之前是否会处理枚举器返回的对象?”
答:答案当然是否定的。它除了提供一种方便的方法来为枚举中的每个对象运行一次代码之外,什么也不做。
或者它是否意味着:
问:“在幕后,foreach 使用一个可枚举对象。即使迭代器块中存在异常,它也会在调用 foreach 后被释放吗?”
答:答案是(仍然相当明显)是的!由于语法不提供对枚举器的访问,因此它有责任处理它。
第二个问题的答案是产生混乱的地方,因为人们听说 foreach 通过 try/finally 块扩展为 while 块。最后的目的是确保如果枚举器实现了 IDisposable,则该枚举器将被释放。
如果您需要亲自查看:参见它在这里起作用
希望这有助于澄清! ;)
This question / answer is poorly worded.
It is not clear if the question asked is:
Q: "Does foreach dispose objects returned by the enumerator before moving to the next?"
A: The answer is of course, NO. It does nothing except provide a convenient way to run some code once for each object in an enumeration.
Or whether it means:
Q: "Under the hood, foreach uses an enumerable object. Does this get disposed after the call to foreach, even if there's an exception in the iterator block?"
A: The answer is (still fairly obviously) YES! Since the syntax does not provide you access to the enumerator, it has the responsibility to dispose it.
The answer to the second question is where the confusion arises, since people have heard that foreach expands to a while block with a try/finally block. The purpose of that finally is to ensure that the enumerator is disposed if it implements IDisposable.
In case you need to see it for yourself: See it in action here
Hope this helps clarify! ;)