수색…


통사론

  1. Contract.Requires (조건, userMessage)

    Contract.Requires (조건, userMessage)

    Contract.Result <T>

    Contract.Ensures ()

    Contract.Invariants ()

비고

.NET은 System.Diagnostics 네임 스페이스에있는 Contracts 클래스를 통해 Contract by Design 아이디어를 지원하며 .NET 4.0에서 도입되었습니다. 코드 계약 API에는 코드의 정적 및 런타임 검사를위한 클래스가 포함되어 있으며 메소드 내에서 전제 조건, 사후 조건 및 불변 조건을 정의 할 수 있습니다. 전제 조건은 메소드가 실행되기 전에 매개 변수가 충족해야하는 조건, 메소드 완료시 검증 된 사후 조건 및 메소드의 실행 중에 변경되지 않는 조건을 정의하는 불변 조건을 지정합니다.

코드 계약이 필요한 이유는 무엇입니까?

응용 프로그램이 실행 중일 때 응용 프로그램의 추적 문제는 모든 개발자와 관리자의 주된 관심사 중 하나입니다. 추적은 다양한 방법으로 수행 될 수 있습니다. 예를 들어 -

  • 응용 프로그램에서 추적을 적용하고 응용 프로그램이 실행 중일 때 응용 프로그램의 세부 정보를 얻을 수 있습니다

  • 응용 프로그램을 실행할 때 이벤트 로깅 메커니즘을 사용할 수 있습니다. 이벤트 뷰어를 사용하여 메시지를 볼 수 있습니다.

  • 특정 시간 간격 후에 성능 모니터링을 적용하고 응용 프로그램에서 실제 데이터를 쓸 수 있습니다.

코드 계약은 응용 프로그램 내에서 문제를 추적하고 관리하기 위해 다른 접근 방식을 사용합니다. 선행 조건, 사후 조건 및 메서드에 대한 불변 식의 도움으로 코드 호출에서 반환 된 모든 내용을 확인하는 대신 메서드에 들어오고 나가는 모든 내용이 올바른지 확인하십시오.

전제 조건

namespace CodeContractsDemo
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.Contracts;
 
    public class PaymentProcessor
    {
        private List<Payment> _payments = new List<Payment>();
 
        public void Add(Payment payment)
        {
            Contract.Requires(payment != null);
            Contract.Requires(!string.IsNullOrEmpty(payment.Name));
            Contract.Requires(payment.Date <= DateTime.Now);
            Contract.Requires(payment.Amount > 0);
 
            this._payments.Add(payment);
        }
    }
}

사후 조건

public double GetPaymentsTotal(string name)
{     
    Contract.Ensures(Contract.Result<double>() >= 0);
 
    double total = 0.0;
 
    foreach (var payment in this._payments) {
        if (string.Equals(payment.Name, name)) {
            total += payment.Amount;
        }
    }
 
    return total;
}

불변성

namespace CodeContractsDemo
{
    using System;
    using System.Diagnostics.Contracts;
 
    public class Point
    {
        public int X { get; set; }
        public int Y { get; set; }
 
        public Point()
        {
        }
 
        public Point(int x, int y)
        {
            this.X = x;
            this.Y = y;
        }
 
        public void Set(int x, int y)
        {
            this.X = x;
            this.Y = y;
        }
 
        public void Test(int x, int y)
        {
            for (int dx = -x; dx <= x; dx++) {
                this.X = dx;
                Console.WriteLine("Current X = {0}", this.X);
            }
 
            for (int dy = -y; dy <= y; dy++) {
                this.Y = dy;
                Console.WriteLine("Current Y = {0}", this.Y);
            }
 
            Console.WriteLine("X = {0}", this.X);
            Console.WriteLine("Y = {0}", this.Y);
        }
 
        [ContractInvariantMethod]
        private void ValidateCoordinates()
        {
            Contract.Invariant(this.X >= 0);
            Contract.Invariant(this.Y >= 0);
        }
    }
}

인터페이스에 대한 계약 정의

[ContractClass(typeof(ValidationContract))]
interface IValidation
{
    string CustomerID{get;set;}
    string Password{get;set;}
}
 
[ContractClassFor(typeof(IValidation))]
sealed class ValidationContract:IValidation
{
    string IValidation.CustomerID
    {
        [Pure]
        get
        {
            return Contract.Result<string>();
        }
        set
        {
            Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(value), "Customer ID cannot be null!!");
        }
    }
 
    string IValidation.Password
    {
        [Pure]
        get
        {
            return Contract.Result<string>();
        }
        set
        {
            Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(value), "Password cannot be null!!");
        }
    }
}
 
class Validation:IValidation
{
    public string GetCustomerPassword(string customerID)
    {
        Contract.Requires(!string.IsNullOrEmpty(customerID),"Customer ID cannot be Null");
        Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(customerID), "Exception!!");
        Contract.Ensures(Contract.Result<string>() != null);
        string password="AAA@1234";
        if (customerID!=null)
        {
            return password;    
        }
        else
        {
            return null;
        }
         
    }
 
    private string m_custID, m_PWD;
 
    public string CustomerID
    {
        get
        {
            return m_custID;
        }
        set
        {
            m_custID = value;
        }
    }
 
    public string Password
    {
        get
        {
            return m_PWD;
        }
        set
        {
            m_PWD = value;
        }
    }
}

위의 코드에서는 [ContractClass] 속성을 가진 IValidation 이라는 인터페이스를 정의했습니다. 이 속성은 인터페이스에 대한 계약을 구현 한 클래스의 주소를 사용합니다. ValidationContract 클래스는 인터페이스에 정의 된 속성을 사용하고 Contract.Requires<T> 사용하여 null 값을 확인합니다. T 는 예외 클래스입니다.

get 접근 [Pure] 속성으로 표시했습니다. 순수한 속성은 메서드 또는 속성이 IValidation 인터페이스가 구현 된 클래스의 인스턴스 상태를 변경하지 않도록합니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow