2012-11-07 81 views
19

我想在我的代碼庫中開始使用Code Contracts代碼合同+代碼分析

我已經使用代碼分析,並啓用了所有規則,並且實現了零警告的目標。

然而,在使用Contract.Requires(parameter != null)當我從代碼分析,即CA1062得到一個警告:

CA1062:Microsoft.Design:在外部可見的方法「富」,用它之前驗證參數「參數」。

這很不幸,我不想禁用該規則,因爲我覺得它很有用。但我也不想壓制它的每一個錯誤發生。

有沒有解決方案?

+0

是否啓用@DanielHilgarth代碼合同靜態驗證?這可以在項目屬性的代碼合同選項卡中找到(啓用「執行靜態合同檢查」)。更多詳細信息可以在[代碼合同文檔](http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf)中找到 – Mightymuke

回答

4

從框架的版本4.5.2(甚至可能是4.5)開始,可以告訴代碼分析代碼合同執行的合同。首先創建下面的擴展方法和標記屬性

using System; 
    using System.Diagnostics; 
    using System.Diagnostics.CodeAnalysis; 
    using System.Diagnostics.Contracts; 

    /// <summary>Extension methods to enhance Code Contracts and integration with Code Analysis.</summary> 
    public static class ContractExtensions { 
#if RUNTIME_NULL_CHECKS 
    /// <summary>Throws <c>ArgumentNullException{name}</c> if <c>value</c> is null.</summary> 
    /// <param name="value">Value to be tested.</param> 
    /// <param name="name">Name of the parameter being tested, for use in the exception thrown.</param> 
    [ContractArgumentValidator] // Requires Assemble Mode = Custom Parameter Validation 
    public static void ContractedNotNull<T>([ValidatedNotNull]this T value, string name) where T : class { 
     if (value == null) throw new ArgumentNullException(name); 
     Contract.EndContractBlock(); 
    } 
#else 
    /// <summary>Throws <c>ContractException{name}</c> if <c>value</c> is null.</summary> 
    /// <param name="value">Value to be tested.</param> 
    /// <param name="name">Name of the parameter being tested, for use in the exception thrown.</param> 
    [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value")] 
    [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "name")] 
    [ContractAbbreviator] // Requires Assemble Mode = Standard Contract Requires 
    public static void ContractedNotNull<T>([ValidatedNotNull]this T value, string name) where T : class { 
     Contract.Requires(value != null,name); 
    } 
#endif 
    } 

/// <summary>Decorator for an incoming parameter that is contractually enforced as NotNull.</summary> 
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] 
public sealed class ValidatedNotNullAttribute : global::System.Attribute {} 

現在轉換您進入空測試,以以下格式:

/// <summary>IForEachable2{TItem} implementation</summary> 
public void ForEach(FastIteratorFunctor<TItem> functor) { 
    functor.ContractedNotNull("functor"); // for Code Analysis 

    TItem[] array = _array; 
    for (int i = 0; i < array.Length; i++) functor.Invoke(array[i]); 
} 

方法名ContractedNotNull和編譯開關RUNTIME_NULL_CHECKS能當然可以改爲任何適合你的命名風格的東西。

Here is the original blog通知我這種技術,我稍微細化;非常感謝Terje Sandstrom發表他的研究成果。

波多黎各蘇特通過使用附加屬性在此here膨脹,導致調試器和內襯更聰明也:

13

爲了解決這個問題,需要按以下步驟進行:

  1. 禁用CA1062在代碼分析擺脫從代碼分析警告的。目前沒有辦法使代碼分析理解Contract.Requires
  2. 在項目的代碼合同窗格中啓用「執行靜態合同檢查」。
  3. 啓用「隱非NULL義務」
  4. 設置警告級別爲「Hi」(重要的,這是我所缺少的!)

第1步擺脫了CA警告,步驟2至4從代碼合同中啓用至少等效的警告。

+0

Re#1:CA1062可以全局禁用還是僅通過單獨禁止? – Keith

+0

@Keith:您可以在項目屬性的代碼分析部分禁用它。 –

+0

@DanielHilgarth:截至框架V4.5.2,您可以直接通知代碼分析代碼合同執行。 –