Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharpNotesForProfessionals.pdf
Скачиваний:
57
Добавлен:
20.05.2023
Размер:
6.12 Mб
Скачать

Chapter 131: Code Contracts

Section 131.1: Postconditions

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;

}

Section 131.2: Invariants

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);

}

GoalKicker.com – C# Notes for Professionals

654

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);

}

}

}

Section 131.3: Defining Contracts on Interface

[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);

GoalKicker.com – C# Notes for Professionals

655

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;

}

}

}

In the above code, we have defined an interface called IValidation with an attribute [ContractClass]. This attribute takes an address of a class where we have implemented a contract for an Interface. The class ValidationContract makes use of properties defined in the interface and checks for the null values using

Contract.Requires<T>. T is an exception class.

We have also marked the get accessor with an attribute [Pure]. The pure attribute ensures that the method or a property does not change the instance state of a class in which IValidation interface is implemented.

Section 131.4: Preconditions

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)

GoalKicker.com – C# Notes for Professionals

656

{

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);

}

}

}

GoalKicker.com – C# Notes for Professionals

657