2012-11-07 27 views
19

Tôi nghĩ về việc bắt đầu sử dụng Code Contracts trong cơ sở mã của tôi.Hợp đồng mã + Phân tích mã

Tôi đã sử dụng Phân tích mã với tất cả các quy tắc được bật và mục tiêu không có cảnh báo.

Tuy nhiên, khi sử dụng Contract.Requires(parameter != null) tôi nhận được một cảnh báo từ Mã Phân tích, cụ thể là CA1062:

CA1062: Microsoft.Design: Trong phương pháp bên ngoài có thể nhìn thấy 'Foo', xác nhận tham số 'thông số' trước khi sử dụng nó.

Thật không may, tôi không muốn vô hiệu quy tắc đó vì tôi thấy hữu ích. Nhưng tôi cũng không muốn ngăn chặn mọi sự xuất hiện sai lầm của nó.

Có giải pháp nào không?

+0

@DanielHilgarth Bạn đã kích hoạt các hợp đồng đang xác minh tĩnh ? Điều này có thể được tìm thấy trong tab hợp đồng mã của thuộc tính dự án (cho phép "Thực hiện kiểm tra hợp đồng tĩnh").Bạn có thể tìm thêm chi tiết trong [Tài liệu Hợp đồng Mã] (http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf) – Mightymuke

Trả lời

4

Kể từ phiên bản 4.5.2 của khuôn khổ (thậm chí có thể là 4.5), có thể cho biết Phân tích mã về các hợp đồng đang được thực thi bởi Hợp đồng mã. Đầu tiên tạo ra các phương pháp khuyến nông sau và thuộc tính marker

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 {} 

và bây giờ chuyển đổi mục null-kiểm tra của bạn sang định dạng sau:

/// <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]); 
} 

Tên phương pháp ContractedNotNull và công tắc biên soạn RUNTIME_NULL_CHECKS thể tất nhiên được thay đổi thành bất kỳ thứ gì phù hợp với kiểu đặt tên của bạn.

Here is the original blog thông báo cho tôi về kỹ thuật này, mà tôi đã tinh chế một chút; rất cám ơn Terje Sandstrom đã xuất bản nghiên cứu của ông.

Rico Suter mở rộng trên here này bằng cách sử dụng thuộc tính bổ sung để trình gỡ lỗi và inliner thông minh thêm:

13

Để giải quyết vấn đề này, các bước sau đây cần phải được thực hiện:

  1. Disable CA1062 trong Phân tích Mã để thoát khỏi những cảnh báo từ Phân tích Mã. Hiện tại không có cách nào để làm cho Phân tích mã hiểu được Contract.Requires.
  2. Bật "Thực hiện kiểm tra hợp đồng tĩnh" trong ngăn Hợp đồng mã của dự án.
  3. Enable "Implicit Nghĩa vụ Non-Null"
  4. Set Cảnh Cáo để "hi" (quan trọng, đó là những gì tôi đã mất tích!)

Bước 1 được thoát khỏi những cảnh báo CA, bước 2 để 4 cho phép cảnh báo từ các Hợp đồng Mã ít nhất là tương đương.

+0

Re: 1: CA1062 có thể bị vô hiệu hóa trên toàn cầu hay chỉ thông qua các lệnh cấm cá nhân ? – Keith

+0

@Keith: Bạn có thể vô hiệu hóa nó trong phần Phân tích mã của thuộc tính dự án của bạn. –

+0

@DanielHilgarth: Với V4.5.2 của khung công tác, bạn có thể trực tiếp thông báo cho Code Analysis về các Hợp đồng Mã đang được thi hành. –