我一直在编写一些自定义WinForm控件,这些控件执行相当大量的绘图,因此往往会有很多基于图形的一次性字段(画笔,笔,位图等)。因此我的控件是Dispose()方法必须在每个上面调用Dispose。
我担心我(或未来的维护者)很容易错过需要处理的字段,要么忘记处理它,要么没有意识到它实现了IDisposable。因此,我在Object上编写了一个非常简单的扩展方法,它找到所有IDisposable字段并处理它们:
static public void DisposeAll(this Object obj)
{
var disposable = obj.GetType()
.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
.Select(fi => fi.GetValue(obj))
.Where(o => o != null && o is IDisposable)
.Cast<IDisposable>();
foreach (var d in disposable) d.Dispose();
}
我的问题基本上是这是否合理。我无法想象它可能搞砸了什么,但后来我对WinForms的内部工作方式并不是特别熟悉,而这似乎是那种可能会引起恼人的错误的事情(弄乱反思和处理)。 / p>
答案 0 :(得分:4)
通常您不想处置所有一次性成员。例如。对父表格的引用。
答案 1 :(得分:2)
不,这不是一个好方法。您在OnPaint方法中创建的绘图对象应始终是局部变量,由使用语句包装。您的方法需要声明一个类,只是为了存储这些对象。痛苦而低效。此外,您将处置永远不会被丢弃的物品。就像预制笔和画笔一样,例如Pens.Black。
答案 2 :(得分:1)
很难说它是否适用于您的特定情况;我按Dispose()
调用的顺序看到了最大的问题。如果一个非托管句柄依赖于另一个,你将会遇到绘图,内存等奇怪的问题。
IMHO。
答案 3 :(得分:0)
我认为这很危险。如果你实现了这个想法,那么对象将被丢弃(如果它是一次性的),并且在某些情况下,比如当你需要对象出现时,它将会消失。
自动化适用于您确定不会被回头的对象。
答案 4 :(得分:0)
您可以使用FxCop或Code Analysis(Visual Studio 2010 Premium或更高版本)。
规则CA2213将查找您忘记处理的字段。