C# Language
Kodavtal
Sök…
Syntax
Contract.Requires (Condition, userMessage)
Contract.Requires (Condition, userMessage)
Contract.Result <T>
Contract.Ensures ()
Contract.Invariants ()
Anmärkningar
.NET stöder Design by Contract-idén via sin kontraktsklass som finns i System.Diagnostics namnutrymme och introduceras i .NET 4.0. Code Contracts API innehåller klasser för statisk och runtime-kontroll av kod och låter dig definiera förutsättningar, postconditions och invarianter inom en metod. Förutsättningarna specificerar villkoren som parametrarna måste uppfylla innan en metod kan utföra, postvillkor som verifieras efter avslutad metod, och invarianterna definierar villkoren som inte ändras under utförandet av en metod.
Varför behövs kodavtal?
Att spåra frågor om en applikation när din applikation körs är en av de främsta problemen för alla utvecklare och administratörer. Spårning kan utföras på många sätt. Till exempel -
Du kan tillämpa spårning på vår ansökan och få information om en applikation när applikationen körs
Du kan använda händelseloggningsmekanismen när du kör applikationen. Meddelandena kan ses med Event Viewer
Du kan tillämpa Performance Monitoring efter ett visst tidsintervall och skriva direktdata från din ansökan.
Code Contracts använder ett annat tillvägagångssätt för att spåra och hantera frågor inom en applikation. I stället för att validera allt som returneras från ett metodsamtal, kodar kontrakt med hjälp av förutsättningar, postvillkor och invarianter om metoder, se till att allt som kommer in och lämnar dina metoder är korrekt.
förutsättningar
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);
}
}
}
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;
}
invarianter
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);
}
}
}
Definiera kontrakt på gränssnitt
[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;
}
}
}
I ovanstående kod har vi definierat ett gränssnitt som kallas IValidation
med ett attribut [ContractClass]
. Detta attribut tar en adress till en klass där vi har implementerat ett kontrakt för ett gränssnitt. Klassen ValidationContract
använder egenskaper definierade i gränssnittet och kontrollerar om nollvärdena används med Contract.Requires<T>
. T
är en undantagsklass.
Vi har också markerat get-accessorn med ett attribut [Pure]
. Det rena attributet säkerställer att metoden eller en egenskap inte ändrar instansstillståndet för en klass där IValidation
implementeras.