如果你有一個刷子和筆,如:如何處理我們沒有參考的一次性物體?
Brush b = new SolidBrush(color);
Pen p = new Pen(b);
,並處理它們像這樣:
b.Dispose();
p.Dispose();
你將如何處置它,如果它是:
Pen p = CreatePenFromColor(color)
這將創建刷和筆爲你?我不能在這個方法裏面放置畫筆,對吧?
這是一種不用於一次性物品的方法嗎?
編輯:我的意思是,你如何處置刷?
如果你有一個刷子和筆,如:如何處理我們沒有參考的一次性物體?
Brush b = new SolidBrush(color);
Pen p = new Pen(b);
,並處理它們像這樣:
b.Dispose();
p.Dispose();
你將如何處置它,如果它是:
Pen p = CreatePenFromColor(color)
這將創建刷和筆爲你?我不能在這個方法裏面放置畫筆,對吧?
這是一種不用於一次性物品的方法嗎?
編輯:我的意思是,你如何處置刷?
這是CreatePenFromColor方法處理Brush實例的工作。它一目瞭然並不明顯,但如果您深入研究Pen類的實現,您會發現它不能保持傳入的Brush實例。相反,它只是用它來計算一些值。因此,Brush實例沒有理由超出對CreatePenFromColor的調用,並且該方法應該處理該實例。
謝謝Jared,我不知道。 – 2009-10-08 18:12:51
這不一定是真的。 Pen構造函數將畫筆的句柄傳遞給'GdipCreatePen2'。我不知道'GdipCreatePen2'是否需要刷子保持活動狀態(該功能幾乎沒有記錄),但我猜測它確實存在。請記住,畫筆可以是帶有圖像的「TextureBrush」,並且您不希望筆在內存中創建圖像的單獨副本,以便您可以放置畫筆。 – SLaks 2009-10-08 18:25:24
@Slaks,GdipCreatePen2 AFAIK不需要它活着。我通過非常有限的文檔挖掘,只需要安裝筆,而不是維護它。 – JaredPar 2009-10-08 18:32:31
你完成後仍然需要處理它。
例如,你可以這樣調用它:
using (Pen p = CreatePenFromColor(color))
{
// do something
}
如果一個方法返回一個IDisposable的對象,這是你的職責,處置它。
[編輯]現在我得到了問題 - 你正在使用鋼筆(畫筆b)的構造函數。
a。在這種情況下,似乎筆不需要刷機實例構造後,所以你的方法看起來是這樣的:
public Pen CreatePenFromColor(Color c)
{
using (Brush b = new SolidBrush(c))
{ return new Pen(b); }
}
灣爲什麼不簡單地使用Pen(Color color)?
public Pen CreatePenFromColor(Color c)
{
return new Pen(c);
}
c。 (關於評論)如果筆在內部持有對刷子的引用,那麼在完成筆之前,您將無法處理它。在這種情況下,我會去的一類會爲我做的工作:
public class PenHelper : IDisposable
{
private readonly Brush _brush;
public PenHelper(Color color)
{
_brush = new SolidBrush(color);
}
public Pen CreatePen()
{
return new Pen(_brush);
}
public void Dispose()
{
_brush.Dispose();
}
}
,然後用它是這樣的:
using (PenHelper penHelper = new PenHelper(Color.Black))
{
using (Pen pen = penHelper.CreatePen())
{
// do stuff
}
}
免責聲明:IDisposable接口是根據準則沒有實現,但而僅用於演示。此外,整個示例僅用於顯示如何在需要時封裝引用。當然,你應該選擇Pen(彩色)。
+1「爲什麼人們創造筆刷來創造筆?!?」 – 2009-10-08 18:29:52
謝謝。在你的例子中,刷子b會在Pen返回時被處置,對嗎?如果Pen在內部提到刷B,那麼它會舉一個例子嗎?就是想。 – 2009-10-08 18:32:36
感謝您的擴展示例。 – 2009-10-08 18:43:42
當一種方法取消了一個IDisposable實例時,它同時移交了終生管理職責。
現在是調用者在使用後處理對象的責任。如果該對象包含其他IDisposable對象,那麼按照約定,我們必須期望容器在我們處置它時正確處理它的子項 - 否則這將意味着容器中存在一個錯誤。
在您的具體示例中,您應該期望Pen在處置它時處置其內部的Brush實例。
顏色也是一次性的嗎? – 2009-10-08 18:09:05
不,顏色是一個結構。 – Groo 2009-10-08 18:10:04
@Joan Venge:'Typo' - 我在糾正您的評論的同時...... – 2009-10-08 18:10:44
您的問題沒有一般解決方案。
在您的具體示例中,這不是問題,因爲Pen具有直接使用Color的構造函數。有些類會自己處理它們的構造函數參數(特別是Stream相關的類)。檢查反射器中的每個類。
如果您要返回的類從Component繼承,則可以爲其Disposed事件添加處理程序。
如果你要返回的類不是密封的,你可以創建一個繼承的版本來處理你創建它的對象。
最後,如果你真的想,你可以創建一個包裝類,它包含你要返回的對象並處理構造函數參數。但是,這會很混亂,我不會推薦它。
我的一個與許多與圖形相關的類peeves是沒有一致的模式來處理這些問題。真正需要的是實現部分引用計數的手段。不在COM風格中,傳遞引用需要不斷地引用計數,但是通過給定IDisposable圖形對象,可以請求另一個共享相同底層資源的實例。資源本身將被封裝在帶有引用計數器的共享對象中。創建另一個引用實例會增加計數器;在引用實例上調用Dispose會減少它。這將避免引用計數的95%的開銷,同時保留99%的收益。
o.O我不知道那個刷子和筆實現了IDisposable ... – 2009-10-08 18:09:17
哈哈,它當然會。 – 2009-10-08 18:11:51
但是這個Brush究竟在哪裏引用?如果你只是返回一個Pen作爲方法結果,爲什麼(以及在哪裏)創建它? – Groo 2009-10-08 18:12:47