LINQ的IEnumerable扩展是否会调用其IEnumerable的Dispose方法?

21

假设我编写了一个实现IEnumerable接口的类,并返回一个IEnumerator,它不仅仅是因为是枚举器而需要IDisposable,而是因为它具有需要在枚举完成后进行Dispose()的托管资源,只要我的枚举器在其IDisposable实现中正确地处理这些托管资源,我能相信以下代码会Dispose()那些托管资源吗?

return (new MyClass()).Select(x => x);

编辑:这个问题看起来与那个被管理员标记为类似的问题相似,但在我看来语义上不同(在我提出问题之前就看到了)


5
不必担心如何处理由John Skeet回答中提到的“dispose”问题... [链接] - Janty
如果你想要确定,你可以在你的Dispose()中加入一个Console.WriteLine()并查看它是否被触发。 - Matt Rowland
1
如果他的MyClass实现了IDisposable接口,那么Dispose()方法将被调用。垃圾回收器不会调用Dispose()方法。 - Matt Rowland
@MattRowland - 关于 MyClass 的问题不对。在 OP 的代码中,.Dispose 不会new MyClass() 上被调用。 - Enigmativity
1
我并不是说它会这样做。我是在说他可以通过在Dispose()方法中放置一个Console.WriteLine()来检查它是否会这样做。 - Matt Rowland
我当然检查了这个单一方法,但我想知道是否可以将其应用于任何LINQ枚举。Matt是正确的,Dispose()不会从垃圾回收中调用。因此,“托管资源”。 - humanoidanalog
1个回答

13

是的,您可以在LINQ方法的内部依赖Dispose()对您的迭代器进行调用。

在由微软发布的参考代码中,迭代器的使用分为三类:

  • foreach循环内使用迭代器,这会确保调用Dispose(),或者
  • 将迭代器与while循环一起使用;这些迭代器需要显式处理
  • using块中获取迭代器,这会确保自动处理。

在所有这些情况下,库都确保在完成后调用迭代器的Dispose()方法。


所以,只有在 foreach 的情况下,Dispose 才会在“枚举”时自动调用吗? - user2864740
@user2864740 是的。如果你在forwhile中手动使用Iterator<T>,那么你应该自己调用Dispose() - Sergey Kalinichenko

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