Code Contracts är en ny funktion som har fötts fram ur Microsoft Research och som kommer att finnas med i .NET Framework 4.0. Med den funktionen kan man, som hörs på namnet, definiera kontrakten på sin kod på ett bättre sätt. Dessa kontrakt kontrolleras antingen vid kompilering eller exekvering.
Jag vill ge några korta exempel här. Se nedan under rubriken länkar för att hitta vidare information. Ladda ned Code Contract MSI för Visual Studio 2010, Beta 1, för att få dessa exempel att fungera.
Exempel 1
Följande kod är en klass med namnet Customer som har en publik metod Age. Age har en parameter som är definierad som nullable int. Detta är en rätt normal kod, eller hur?
class Customer {
private int Year;
public void Age(int? numberOfYears) {
Year =+ numberOfYears.Value;
}
}
Slår man på Code Contract, som finns under Properties för projektet…
…och sedan bygger projektet, får man upp följande felmeddelande:
Det visar på att Year inte kan vara null, vilket i sin tur gör att numberOfYears inte heller kan vara null. Rad 1 ger ett förslag på ett sätta att explicit ange denna kontraktsregel iställer för på det implicita sättet som nu är. Rad 2 talar om att vi inte har något som verkligen testar att denna kontraktsregel följs.
Det enklaste sättet att fixa till detta är att ändra följande kodrad.
class Customer {
private int Year;
public void Age(int? numberOfYears) {
if(numberOfYears.HasValue) Year += numberOfYears.Value;
}
}
Nu genererar kontraktsgranskningen inget fel igen.
Exempel 2
class Customer {
private int Year;
public void Age(int? numberOfYears) {
Contract.Requires(numberOfYears > 1);
Contract.Ensures(Year > Contract.OldValue(Year));
if(numberOfYears.HasValue) Year += numberOfYears.Value;
}
}
I denna kod har vi lagt till två statiska metoder ifrån klassen Contract. Den finns förresten under namnrymden System.Diagnostics.Contracts. Requires användas för att definiera ett kontrakt för de förutsättningar som krävs innan metoden körs och Ensure gör det möjligt att beskriva ett kontrakt som skall gälla vid utgången av metoden. OldValue använts för att kunna använda en variabels värde som den var vid ingången i metoden.
Avslutning
Detta var en mycket kort introduktion till kodkontrakt. Men innan jag slutar vill jag ta upp en sak till. Vad gör vi med alla de tester som vi redan har skrivit i våra metoder, if-then-throw. Dessa kan man fortfarande ha kvar och genom att använda EndContractBlock ochså använda dem för att skapa kodkontrakt.
class Customer {
private int Year;
public void Age(int? numberOfYears) {
if (numberOfYears <= 0)
throw new ArgumentException();
Contract.EndContractBlock();
}
}
Mer information
Det finns mycket mer man kan göra med kodkontrakt. Ett bra sätt att börjar titta vidare på den här funktionen är att gå till DevLabs sida för Code Contracts. Där finns dokumentation och exempel.
Är väl inte direkt en ny funktion men ny för .Net förstås. Kontrakt har ju funnits i programmeringsspråket Eiffel i snart 25 år.
Men annars tycker jag det är bra det kommit till .Net.
Posted by: Fredrik | 2009-10-20 at 19.17
Du har helt rätt. En av föregångarna är just Eiffel.
/dag
Posted by: Dag | 2009-10-26 at 07.26