2011-08-07 32 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

相關問題