自动处理扩展方法合理吗?

时间:2010-10-08 13:26:19

标签: c# .net extension-methods dispose

我一直在编写一些自定义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>

5 个答案:

答案 0 :(得分:4)

通常您不想处置所有一次性成员。例如。对父表格的引用。

答案 1 :(得分:2)

不,这不是一个好方法。您在OnPaint方法中创建的绘图对象应始终是局部变量,由使用语句包装。您的方法需要声明一个类,只是为了存储这些对象。痛苦而低效。此外,您将处置永远不会被丢弃的物品。就像预制笔和画笔一样,例如Pens.Black。

答案 2 :(得分:1)

很难说它是否适用于您的特定情况;我按Dispose()调用的顺序看到了最大的问题。如果一个非托管句柄依赖于另一个,你将会遇到绘图,内存等奇怪的问题。

IMHO。

答案 3 :(得分:0)

我认为这很危险。如果你实现了这个想法,那么对象将被丢弃(如果它是一次性的),并且在某些情况下,比如当你需要对象出现时,它将会消失。

自动化适用于您确定不会被回头的对象。

答案 4 :(得分:0)

您可以使用FxCopCode Analysis(Visual Studio 2010 Premium或更高版本)。

规则CA2213将查找您忘记处理的字段。