C# Language
Codecontracten
Zoeken…
Syntaxis
Contract.Requires (conditie, userMessage)
Contract.Requires (conditie, userMessage)
Contract.Result <T>
Contract.Ensures ()
Contract.Invariants ()
Opmerkingen
.NET ondersteunt het Design by Contract-idee via de klasse Contracts in de naamruimte System.Diagnostics en geïntroduceerd in .NET 4.0. Code Contracts API bevat klassen voor statische en runtime-controles van code en stelt u in staat binnen een methode randvoorwaarden, postcondities en invarianten te definiëren. De randvoorwaarden specificeren de voorwaarden waaraan de parameters moeten voldoen voordat een methode kan worden uitgevoerd, postvoorwaarden die worden geverifieerd na voltooiing van een methode, en de invarianten definiëren de voorwaarden die niet veranderen tijdens de uitvoering van een methode.
Waarom zijn codecontracten nodig?
Het bijhouden van problemen van een toepassing wanneer uw toepassing actief is, is een van de belangrijkste zorgen van alle ontwikkelaars en beheerders. Tracking kan op veel manieren worden uitgevoerd. Bijvoorbeeld -
U kunt tracering toepassen op onze applicatie en de details van een applicatie opvragen wanneer de applicatie actief is
U kunt gebeurtenisregistratiemechanisme gebruiken wanneer u de toepassing uitvoert. De berichten kunnen worden bekeken met behulp van Logboeken
U kunt Prestatiemonitoring na een specifiek tijdsinterval toepassen en live gegevens vanuit uw toepassing schrijven.
Code Contracts gebruikt een andere aanpak voor het volgen en beheren van problemen binnen een applicatie. In plaats van alles wat wordt geretourneerd uit een methodeaanroep te valideren, zorgt Codecontracten met behulp van randvoorwaarden, postcondities en invarianten voor methoden ervoor dat alles wat u invoert en verlaat uw methoden correct is.
randvoorwaarden
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);
}
}
}
postcondities
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;
}
invarianten
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);
}
}
}
Contracten definiëren op 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);
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 de bovenstaande code hebben we een interface IValidation
met de naam IValidation
met een kenmerk [ContractClass]
. Dit kenmerk heeft een adres van een klasse waarvoor we een contract voor een interface hebben geïmplementeerd. De klasse ValidationContract
maakt gebruik van eigenschappen die in de interface zijn gedefinieerd en controleert op de nulwaarden met Contract.Requires<T>
. T
is een uitzonderingsklasse.
We hebben de get accessor ook gemarkeerd met een kenmerk [Pure]
. Het pure attribuut zorgt ervoor dat de methode of een eigenschap de instantiestatus van een klasse waarin IValidation
interface is geïmplementeerd niet verandert.