2013-10-10 103 views
3

在下面的代碼中,我得到一個XmlNodeList作爲返回值從XmlDocument.SelectNodes()我應該處理的XmlNodeList

foreach (XmlNode node in doc.SelectNodes(xPath)) 
{ 
    // Do stuff 
} 

事實證明,XmlNodeList實現IDisposable。這是否意味着每次我想迭代XmlDocument.SelectNodes()的返回值時,我都應該把它放在一個局部變量中,並確保它被丟棄(即將其置於using塊中)?

像這樣:

using(XmlNodeList nodes = doc.SelectNodes(xPath)) 
{ 
    foreach (XmlNode node in nodes) 
    { 
     // Do stuff 
    } 
} 
+0

看看這個:http://stackoverflow.com/questions/14398798/why-is-xmlnodelist-disposable – Chris

+0

@Chris:我看到了。雖然@AgentFire指出我應該調用Dispose()還是不全面,但我沒有向我清楚,我明顯應該這麼做。它確實使'SelectNodes()'不太吸引人。 –

+0

我同意 - 不得不處置它並不好玩。就我個人而言,我想我會忘記我曾經閱讀過這些,並繼續像以前一樣不加處理...... – Chris

回答

6

System.Xml命名空間是,呃,靠不住的。最好的方式,我可以把它。 XmlNodeList是一個抽象類,它繼承了IDisposable並實現了一次性模式,但本身並不做任何事情。

有三個內部類派生自XmlNodeList。其中一個實際上覆蓋了Dispose(bool)方法,XmlElementList。該類有一個類型爲XmlElementListener的私有字段。而另一個內部班級,並不是那麼明顯,它似乎在「聽」列出變化。 Dispose方法(等待它)取消訂閱兩個事件處理程序。

這打破了書中的每一條規則,它是從來沒有正確的濫用IDisposable。不幸的是,你必須走散步,如果你不調用Dispose(),那麼看看這個listener是否被實例化,以及這些事件處理程序是否會在你的程序中造成持久泄漏是幾乎不可能的。你最好打電話給它。

許多令人敬畏的代碼在.NET Framework中。好的代碼總是需要糟糕的代碼才能明顯地看到好的代碼有多好。這是System.Xml的工作。

+0

哪一部分「違反書中的每一條規則」?還是全部呢? – Andrew

+0

'IDisposable'旨在用於任何確定性的通用清理,而不僅僅用於處理非託管資源。微軟在不久前改變了他們的觀點。查看完全相同的使用模式的觀察者模式。這不違反任何規則。 –

+0

我最好援引以下母語爲英語的人:https://www.google.com/#q=eric+lippert+idisposable+abuse –