2014-08-29 74 views
27

我正在對Visual Studio進行擴展。在代碼中,我使用Code Contracts來進行斷言和檢查。我將警告選項級別設置爲高。如何讓Code Contracts忽略特定的程序集引用?

我想要做的是保持警告級別,同時忽略對EnvDTE引用所做的任何檢查。

考慮下面的代碼示例:

public static string GetAbsoluteOutputFolder(EnvDTE.Project project) 
{ 
    if (project == null) throw new ArgumentNullException("project"); 

    var path = 
     project.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString(); 
    //... 
} 

從我目前的設置,CC需要我分配path變量之前添加以下檢查:

Contract.Assume(project.ConfigurationManager != null); 
Contract.Assume(project.ConfigurationManager.ActiveConfiguration != null); 
Contract.Assume(project.ConfigurationManager.ActiveConfiguration.Properties != null); 

因此想什麼,我這裏要做的是告訴CC「信任」EnvDTE並忽略這些類型及其屬性。

我認爲「對外部API樂觀」的CC選項服務於此目的;事實證明它不是。

是否有辦法讓我的行事方式不需要較低的警告級別

編輯:我想要一個解決方案,可以在項目級別工作,並仍然可以執行「常規」檢查。

+1

如果是我,我只想添加您想省略的支票。如果你的代碼因爲EnvDTE.Project中的Null引用而爆炸了,那麼這些檢查應該讓你知道問題的確切位置,而不是試圖猜測Null在哪裏。 – 2014-12-04 20:51:50

+0

@MikeBurdick事情是,這些屬性中的一些很可能永遠不會爲空。但是由於這個程序集沒有用合同進行編譯,所以引擎無法分辨。因此,它將這些視爲任何沒有合同的財產,強制對一次又一次的同一財產使用毫無意義的檢查。如果有一個全局的,一次性的方法來強制執行'Configuration.Properties'(例如)永遠不會返回null我很樂意使用它,但沒有。所以恕我直言,較小的邪惡就是告訴CC簡單地忽略屬於該特定程序集的任何代碼。 – Crono 2015-03-05 17:20:09

回答

4

不容提供一個詳細的解決方案,但是這應該是通過使用的基本特性或System.Diagnostics.CodeAnalysis.SuppressMessage上裝配水平解:

[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Contracts", "Whatever")] 

可以使用的「目標」屬性在SuppressMessageAttribute只忽略特定類型/方法/命名空間的消息:

[SupressMessage("Microsoft.Contracts", "CC1055", Scope="Member", Target="YouNamespace.EnvDTE.Project"] 

請注意,我使用的參數只是一個不錯的選擇,you'll必須找出正確的範圍,郵件ID以及自己的目標: )在旁註中,我認爲屬性是有條件的(「CODE_ANALYSIS」)。

對此問題的官方建議解決方案是創建某種包裝,在您的情況下可能會創建或包含您的EnvDTE.Project對象的存儲庫。然後,您可以在那裏添加所需的Contract.Ensures。

+0

如果我不擁有所述組件的代碼,如何發出組件級警告? – Crono 2015-03-31 13:05:09

+1

@Crono:您可以使用SuppressMessageAttribute的「Target」屬性抑制外部庫上的消息,我會將其添加到答案中。 – Mecaveli 2015-04-01 15:50:39

0

您是否在組裝層面嘗試過某些方法: [assembly: Contracts.ContractVerification(false)]

你應該能夠動態地做到這一點:https://msdn.microsoft.com/en-us/library/bb458043.aspx

希望這有助於

+1

如果我正確理解此屬性,它將只會阻止該程序集中的合同驗證。 OP想要的是忽略使用程序集創建的所有警告。 – 2016-07-11 14:02:10

1

我不認爲這是有可能解決的問題,但由於C#6.0有至少減輕了一種解決方法痛了一下:

而不是

Contract.Assume(project.ConfigurationManager != null); 
Contract.Assume(project.ConfigurationManager.ActiveConfiguration != null); 
Contract.Assume(project.ConfigurationManager.ActiveConfiguration.Properties != null); 

你現在可以寫

Contract.Assume(project.ConfigurationManager?.ActiveConfiguration?.Properties != null);