我有各種類包裝IntPtr
。它們不存儲自己的數據(除了指針),而是使用屬性和方法使用非託管庫在指針中公開數據。它運行良好,但我已經到了需要能夠從其他包裝器對象中引用這些包裝器對象的地步。例如:我該如何避免在整個地方創建新的包裝對象?
public class Node {
private IntPtr _ptr;
public Node Parent {
get { return new Node(UnmanagedApi.GetParent(_ptr)); }
}
internal Node(IntPtr ptr) {
_ptr = ptr;
}
}
現在,我可以簡單地返回一個new Node(parentPtr)
(如上),但對於有成千上萬節點的潛力。這不是一個壞主意,因爲多個包裝對象最終可能指向相同的IntPtr
?
我能做些什麼來解決這個問題?我想過使用一個靜態KeyedCollection
類,它使用每個IntPtr
作爲關鍵。所以,不要每次都返回一個新的Node
,我可以查看它。但那會帶來線程問題,對吧?
有沒有更好的方法?
非託管庫處理狀態。我的課程簡單地給它一個.NET外觀。不過,我明白你對刪除對象的看法。它們是一次性的,但後來我意識到,如果它們被存儲在「KeyValuePair」中,那麼這些對象無論如何都不會被垃圾收集。我所關心的是擁有數千個基本上都是基本相同的東西的開銷。它會甚至是顯而易見的,還是我只是爲了優化而優化? C++/CLI不是一種選擇,因爲我想稍後將它移植到Mono中。 – 2009-12-28 09:05:42
一般來說,創建數千個對象會導致垃圾收集器出現一些令人頭疼的問題。 另一種選擇是傳遞指針,並有一個幫助類,它接受一個指針並返回所需的數據。例如Helper.GetIdFromUnmanagedObject(myPtr),而不是讓對象具有自己的行爲。從OO的角度來看,並不是那麼漂亮,但至少你只有非託管對象,而不是包裝。 – Paolo 2009-12-28 09:14:49
是的,我基本上已經這樣做了(非託管API的構建有點像這樣),但我真的想用枚舉器將它與框架混合,以使其儘可能直觀。我想我會等待,看看它是如何發生的,並在實際上成爲問題時決定靜態引用集合。我仔細看了一眼,可能物體會很快被GC'd,因爲它們確實沒有任何指向其他物體的連接(因爲'IntPtrs'實際上是將它們連接在一起的)。 – 2009-12-28 09:22:00