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:
Nguồn
2015-07-26 15:31:57
@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