As part of the Code Contracts Library there are many ways to validate your code whether it be with pre-conditions, post-conditions or object-invariants. All of these are great and can add extreme value to your project. But by default pre-conditions and post-conditions work on single values either at the object level or at a lower level such as string property. However, there is a way to perform some validations upon list of items and you can use Contracts.Exists and Contracts.ForAll.
Contracts.Exists will iterate over a list (or array) and will validate that at least one item in the collection satisfies your condition.
Contract.ForAll will iterate over a list (or array) and will validate that every item in the collection satisfies your condition.
How can you use each of these? Imagine I have a few simple classes as such:
public class TeamStanding
{
public TeamStanding( int place, Team team )
{
Place = place;
Team = team;
}
public Int32 Place { get; set; }
public Team Team { get; set; }
}
public class Team
{
public string Name { get; set; }
}
And we want to create a class called League Information which can be used to gather data about the teams in our league. One of the things we want to gather is a list of standings, however when we return the list of standings we MUST make sure at least one team is in first place. We can satisfy this with a Contracts.Exists call. The code below shows how:
public class LeagueInformation
{
public IList<TeamStanding> GetDivisionStandings()
{
Contract.Ensures( Contract.Exists( Contract.Result<IList<TeamStanding>>(), x => x.Place == 1 ) );
var standings = new List<TeamStanding>
{
new TeamStanding( 11, new Team{Name = "Braves"} ),
new TeamStanding( 2, new Team{Name = "Marlins"} ),
new TeamStanding( 3, new Team{Name = "Mets"} ),
new TeamStanding( 4, new Team{Name = "Nats"} ),
new TeamStanding( 5, new Team{Name = "Phillies"} )
};
return standings;
}
}
As you can see from the above we are using the .Exists in conjunction with a post-condition check. Please keep in mind that you can do this as a pre-condition or simply as a validation inline. I only used a post-condition for sake of example.
Now lets say we want to add another method to the LeagueInformation class which returns a list of all the teams in the league and we want to verify that the list coming out has at least one value and that the team object in each item is non-null. We can satisfy this with a call to Contracts.ForAll. The code below shows how:
public class LeagueInformation
{
public IList<Team> GetDivisionalTeams()
{
Contract.Ensures( Contract.ForAll( Contract.Result<IList<Team>>(), x => x != null ) );
var teams = new List<Team>
{
new Team{Name = "Braves"} ,
new Team{Name = "Marlins"},
new Team{Name = "Mets"} ,
new Team{Name = "Nats"},
new Team{Name = "Phillies"}
};
return teams;
}
}
As you can see we are again using the .ForAll in conjunction with a post-condition, and again this is just for sake of example.
If either of these conditions fail you will receive an error which looks like below (assuming you do not have a try-catch in your code).
If you do not receive an error while trying to validate a negative condition make sure you have turned on runtime checking for the contracts. You can do this by opening the properties dialog for your project and selecting the run-time behavior option. See below:
As you can see using Contracts to validate your list items is dead simple, yet extremely powerful.
Till next time.
Posted
04-20-2010 6:05 AM
by
Derik Whittaker