ContractArgumentValidatorAttribute 类

定义

启用 if-then-throw 旧代码分离为单独的方法,用以重用,并提供对引发的异常和参数的完全控制。

public ref class ContractArgumentValidatorAttribute sealed : Attribute
[System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false)]
[System.Diagnostics.Conditional("CONTRACTS_FULL")]
public sealed class ContractArgumentValidatorAttribute : Attribute
[<System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false)>]
[<System.Diagnostics.Conditional("CONTRACTS_FULL")>]
type ContractArgumentValidatorAttribute = class
    inherit Attribute
Public NotInheritable Class ContractArgumentValidatorAttribute
Inherits Attribute
继承
ContractArgumentValidatorAttribute
属性

注解

如果你的代码使用显式 if-then-throw 代码验证参数,则你可采用执行检查并在失败时引发特定异常的帮助程序方法,如下面的示例所示。

using System;

static class ValidationHelper
{
   public static void NotNull(object argument, string parameterName)
   {
      if (argument == null) throw new ArgumentNullException(parameterName,
                                                            "The parameter cannot be null.");
   }
}

public class Example
{
   public void Execute(string value)
   {
      ValidationHelper.NotNull(value, "value");

      // Body of method goes here.
   }
}
Class ValidationHelper 
   Public Shared Sub NotNull(argument As Object, parameterName As String) 
      If argument Is Nothing Then 
         Throw New ArgumentNullException(parameterName, 
                                         "The parameter cannot be null.")
      End If
   End Sub
End Class

Module Example
   Public Sub Execute(value As String)
      ValidationHelper.NotNull(value, "value")
      
      ' Body of method goes here.
   End Sub
End Module

在此示例中,Execute 具有指定参数值不应为 null 的选择性前置条件。 若要使协定工具能够识别对 ValidationHelper.NotNull 的调用表示协定,可以使用 属性标记被调用的方法 ContractArgumentValidatorAttributeContract.EndContractBlock方法调用应用于使工具能够提取适当的规范,以便生成文档和进行静态检查,如下所示。

using System;
using System.Diagnostics.Contracts;

static class ValidationHelper
{
   [ContractArgumentValidator]
   public static void NotNull(object argument, string parameterName)
   {
      if (argument == null) throw new ArgumentNullException(parameterName,
                                                            "The parameter cannot be null.");
      Contract.EndContractBlock();
   }
}
Imports System.Diagnostics.Contracts

Class ValidationHelper 
   <ContractArgumentValidator> 
   Public Shared Sub NotNull(argument As Object, parameterName As String) 
      If argument Is Nothing Then 
         Throw New ArgumentNullException(parameterName, 
                                         "The parameter cannot be null.")
         Contract.EndContractBlock()
      End If
   End Sub
End Class

除了 if-then-throw 语句之外,协定验证程序方法的协定节可能包含对其他协定验证程序方法的调用。 但是,不允许任何其他协定(如 Contract.RequiresContract.Ensures)。 所有协定工具都会忽略调用后面的 Contract.EndContractBlock 代码。

以下示例演示以现有 NotNull 验证程序方法编写的范围参数验证程序。

using System;
using System.Diagnostics.Contracts;

static class ValidationHelper
{
   [ContractArgumentValidator]
   public static void NotNull(object argument, string parameterName)
   {
      if (argument == null) throw new ArgumentNullException(parameterName,
                                                            "The parameter cannot be null.");
      Contract.EndContractBlock();
   }

   [ContractArgumentValidator]
   public static void InRange(object[] array, int index, string arrayName, string indexName)
   {
      NotNull(array, arrayName);

      if (index < 0)
         throw new ArgumentOutOfRangeException(indexName,
                                               "The index cannot be negative.");
      if (index >= array.Length)
         throw new ArgumentOutOfRangeException(indexName,
                                               "The index is outside the bounds of the array.");
      Contract.EndContractBlock();
   }
}

public class Example
{
   public void Execute(object[] data, int position)
   {
      ValidationHelper.InRange(data, position, "data", "position");

      // Body of method goes here.
   }
}
Imports System.Diagnostics.Contracts

Class ValidationHelper 
   <ContractArgumentValidator> 
   Public Shared Sub NotNull(argument As Object, parameterName As String) 
      If argument Is Nothing Then 
         Throw New ArgumentNullException(parameterName, 
                                         "The parameter cannot be null.")
         Contract.EndContractBlock()
      End If
   End Sub

   <ContractArgumentValidator>
   Public Shared Sub InRange(array() As Object, index As Integer, 
                             arrayName As String, indexName As String)
      NotNull(array, arrayName)
      
      If index < 0 Then 
         Throw New ArgumentOutOfRangeException(indexName, 
                                               "The index cannot be negative.")
      End If                                         
      If index >= array.Length Then 
         Throw New ArgumentOutOfRangeException(indexName, 
                                               "The index is outside the bounds of the array.")
      End If                                                                                              
      Contract.EndContractBlock()
   End Sub
End Class

Module Example
   Public Sub Execute(data() As Object, position As Integer)
      ValidationHelper.InRange(data, position, "data", "position")
      
      ' Body of method goes here.
   End Sub
End Module

从规范的角度来看, Execute 方法具有以下三个协定:

Contract.Requires<ArgumentNullException>(data != null);  
Contract.Requires<ArgumentOutOfRangeException>(position >= 0);  
Contract.Requires<ArgumentOutOfRangeException>(position < data.Length);  

在标准方法中,对协定验证程序方法的调用可与其他协定(如 Contract.EnsuresContract.Requires)自由组合。

构造函数

ContractArgumentValidatorAttribute()

初始化 ContractArgumentValidatorAttribute 类的新实例。

属性

TypeId

在派生类中实现时,获取此 Attribute 的唯一标识符。

(继承自 Attribute)

方法

Equals(Object)

返回一个值,该值指示此实例是否与指定的对象相等。

(继承自 Attribute)
GetHashCode()

返回此实例的哈希代码。

(继承自 Attribute)
GetType()

获取当前实例的 Type

(继承自 Object)
IsDefaultAttribute()

在派生类中重写时,指示此实例的值是否是派生类的默认值。

(继承自 Attribute)
Match(Object)

当在派生类中重写时,返回一个指示此实例是否等于指定对象的值。

(继承自 Attribute)
MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
ToString()

返回表示当前对象的字符串。

(继承自 Object)

显式接口实现

_Attribute.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr)

将一组名称映射为对应的一组调度标识符。

(继承自 Attribute)
_Attribute.GetTypeInfo(UInt32, UInt32, IntPtr)

检索对象的类型信息,然后可以使用该信息获取接口的类型信息。

(继承自 Attribute)
_Attribute.GetTypeInfoCount(UInt32)

检索对象提供的类型信息接口的数量(0 或 1)。

(继承自 Attribute)
_Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr)

提供对某一对象公开的属性和方法的访问。

(继承自 Attribute)

适用于