2011-08-07 184 views
6

有很多问题值得我们感叹,VS2010的代码分析规则CA2000可能过于严格地应用了,但我似乎遇到了它应该被应用的情况,但不是。为什么位图会导致规则CA2000,但图像不会?

考虑下面的代码:

Image srcImage = Image.FromFile(source); 
Bitmap newImage = new Bitmap(newWidth, newHeight); 

using (Graphics gr = Graphics.FromImage(newImage)) 
{ 
    gr.DrawImage(srcImage, new Rectangle(0, 0, newWidth, newHeight)); 
} 
newImage.Save(destination, ImageFormat.Jpeg); 

现在,如果我在这个Visual Studio 2010中运行代码分析,它会抱怨newImage没有被设置(简单的办法,把它放在另一个使用块) ,但它并没有抱怨srcImage(它也有一个Dispose()方法,我从来没有打电话)。有人知道为什么代码分析不会在这里抱怨吗?

回答

0

那么它应该“抱怨srcImage”过,但是我猜因为你将它传递给DrawImage方法“gr.DrawImage(srcImage, new Rectangle(0, 0, newWidth, newHeight));”不抱怨,因此,要么是不够聪明,知道在返回方法之后它不会用于更多操作,或者可能假定您在将要丢弃的实例中使用它。无论如何,您应该使用using作为srcImage,就像您在newImage中所做的一样,并且不要按照此代码分析进行操作。

+0

我以为刚开始,但后来我看到了其他的CA2000问题所有这些规则都是通过将参数传递给另一个函数来触发的规则(尽管通常涉及到构造函数)。奇怪的是,这种烦人的规则(对许多人来说,根据SO问题的数量来判断)在这种情况下是如此宽容的。 –

+0

是的,我同意这很烦人,但是我们应该“像你已经做的那样”不是依靠代码分析来修复我们的代码问题,而是只是用它们来仔细检查,看看我们是否忘记了这里和那里的某些东西...... –

+0

是的......但那种打败了这种工具的目的。我使用它们的原因是,他们可以指出我做错了什么地方,为我省去了通过整个巨型代码库寻找这样的小事情的麻烦。 –

5

CA2000和类似/相关CA2213(DisposableFieldsShouldBeDisposed)和CA1001(TypesOhatOwnDisposableFieldsShouldBeDisposable)规则对于如何识别一次性消费者的“所有权”非常严格。如果使用实例构造函数直接在代码中创建实例,它们将只考虑您的代码是一次性实例的所有者。由于您使用Image.FromFile为srcImage创建实例,因此该规则无法将您的代码识别为所有者。

如果您不同意此规则行为,您可能需要在https://connect.microsoft.com/visualstudio/feedback上创建一个错误报告。 (如果您关心一次性现场规则,您可能希望投票赞成现有的https://connect.microsoft.com/VisualStudio/feedback/details/485291/typesthatowndisposablefieldsshouldbedisposable-rule-ca1001-is-too-permissive建议。)

+0

有没有什么办法可以使我做出这样的规则变更,而不用回头去标记很多具有属性的方法,这些属性表明它们应该被视为接管,放弃或冒用IDisposable的所有权(即根据因素变化的行为一个工具不应该被期望跟踪)?引入这样的行为可能是值得的,但添加足够的标签来获得干净的报告可能是很多工作。 – supercat

+0

@supercat:以这种方式编写规则是非常可行的,以便检测被调用的方法是一种工厂方法,该方法创建一次性的新实例而不将该实例存储在自己的状态中。也就是说,规则将无法处理复杂的创建模式,如IoC使用而不添加一些元数据。但是,任何属性都应该放在工厂方法上,而不是其消费者。 –

+0

如果扫描程序可以看到工厂的代码,则可能确定它们创建并返回新的IDisposable实例。不过,并不是所有的工厂都有可供扫描仪访问的代码。增加对工厂的识别会使扫描器产生更多有用的警告,但也会产生更多虚假警告,除非它还可以识别IDisposable对象何时合法移交;这样的认识会引发一些棘手的问题,尽管...... – supercat

相关问题