Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果从IEnumerator引发异常<;T>;。MoveNext()或.Current,是否仍要处理它?_C#_Exception_Dispose_Idisposable_Ienumerator - Fatal编程技术网

C# 如果从IEnumerator引发异常<;T>;。MoveNext()或.Current,是否仍要处理它?

C# 如果从IEnumerator引发异常<;T>;。MoveNext()或.Current,是否仍要处理它?,c#,exception,dispose,idisposable,ienumerator,C#,Exception,Dispose,Idisposable,Ienumerator,直觉上我认为是的,但我不确定是否有一些约定我不知道。因为我们不知道实现是什么,唯一安全的答案是“是” 然而,直接使用IEnumerator是非常罕见的-foreach更为常见。对于通用的IEnumerator,可以使用using语句: using(var iter = obj.GetEnumerator()) { ... } 即使没有通用版本,您也可以作弊: IEnumerator iter = obj.GetEnumerator(); using(iter as IDisposabl

直觉上我认为是的,但我不确定是否有一些约定我不知道。

因为我们不知道实现是什么,唯一安全的答案是“是”

然而,直接使用
IEnumerator
是非常罕见的-
foreach
更为常见。对于通用的
IEnumerator
,可以使用using语句:

using(var iter = obj.GetEnumerator()) {
    ...
}
即使没有通用版本,您也可以作弊:

IEnumerator iter = obj.GetEnumerator();
using(iter as IDisposable) {
    ...
}
如果iter是可识别的,它将进行处置

任何时候都不必处置一次性物品。[1]

但它们应该是。由于
using
块使用
finally
子句进行处置,并且无论
using
块是正常退出还是通过异常退出,都会执行此操作,因此默认情况下即使遇到异常也会进行处置



[1] 我想可能有一个错误的实现,其中有一个非托管资源,但没有终结器,但正确的操作是实现终结器。

IDisposable
对象可以是连接、文件、事务等时(即,可能存在争议的内容;请注意,这可能在迭代器块中,因此适用于
IEnumerator
情况)-然后等待非确定性GC可能非常糟糕。IMO“必须”非常合适。@Marc:MUST表示强制,不这样做本身就是一个错误。SHOULD表示:您需要一个很好的理由不这样做。框架设计指南(第9.4节)中的注释不同意:[Joe Duffy]“当您处理完对象时,您应该尽力调用Dispose。但是如果所有权变得棘手(例如,由于对象是从多个位置引用的或是在多个线程之间共享的),忽略调用Dispose不会有什么坏处。”。也就是说,我假设在本地“没有坏处”,很明显,如果资源被锁定,你会有问题,但情况并非总是如此。@Richard-由于他无法预测实现,他能说的最好不过是它“应该”没有坏处;而“应该”-乘法引入了很多不可预测性。我明白你的意思,但我个人更希望看到“dispose it”的论点得到尽可能强烈的强化。但论证充分,有效(+1),但可能会误导希望懒惰的初学者。Winforms的Control.dispose()是我知道的一个例子,不处理会导致无法恢复的泄漏。这就是问题,没有黄金法则。@Richard:在许多情况下,确保有效清理未处理的IDisposable是不实际的;实际上,这里提到的IEnumerable情况就是其中之一。作为一个简单的场景,假设IEnumerable需要o当集合即将被修改时接收通知(例如,因为使用写时复制实现了延迟快照语义)。如果集合是长期存在的,并且经常枚举但从未修改过,则每个枚举器的寿命都将与集合的寿命一样长。内存严重泄漏。