LA.NET [EN]

Nov 09

Code Contracts also supports are quantifiers (with several limitations, as we’ll see). This means that you can check a predicate against elements in a collection or interval. You can use the ForAll method for running a predicate over several elements maintained on an collection or interval. The Exists method will let you apply a predicate and see if there is at least one item in the  specified collection or interval that validates that predicate.

Consider these two classes:

public class Person {
        public String Name { get; set; }
}
public class PersonSearcher {
        private String _name;
        private IEnumerable<Person> _people;
        public PersonSearcher SearchFor(String name) {
            _name = name;
            return this;
        }
        public PersonSearcher OnPeople(IEnumerable<Person> people) {
            _people = people;
            return this;
        }
        public Person Get() {
            return _people.SingleOrDefault( p => String.CompareOrdinal(p.Name, _name) == 0);
        }
}

There’s a simple Person class and a PersonSearcher class which checks if a specific person in on a collection of Persons. Suppose that one of the things we’d like to make sure is that all the items on the people collection that are passed as a parameter are non null. This is easily done by using the ForAll method:

public PersonSearcher OnPeople(IEnumerable<Person> people) {
    CodeContract.Requires(
                         CodeContract.ForAll(people, p => p != null));
    _people = people;
    return this;
}

And now you do get verification on all the instances of people passed as an argument. For instance, if you try to run this code, you’ll get a Debug.Assert at runtime:~

var people = new[]
                             {
                                 null,
                                 new Person {Name = "Luis"},
                                 new Person {Name = "John"},
                                 new Person {Name = "Charles"}
                             };
new PersonSearcher().SearchFor("Luis").OnPeople(people);

If the method received an array, you could also use the other overload method:

public PersonSearcher OnPeople(Person[] people) {
  CodeContract.Requires(
   CodeContract.ForAll(0, people.Length, pos => people[pos] != null));
CodeContract.Ensures(_people != null);
_people = people;
return this;
}

The Exists method is really similar to the ForAll method,so I won’t be writing any example to show its usage. On the next post,we’ll start looking at runtime behavior. Keep tuned!

2 comments so far

  1. Ram
    9:20 am - 11-10-2008

    I don”t understand please help me:
    What”s the difference between:

    Contracts.Requires(Contracts.Exists(list, item => SomeTest)

    and

    Contracts.Requires(list.Any(item => SomeTest));

    Does the later one even works ? If yes, why introduce new stuffs like “Exists” ?
    Thanks for your help.

  2. luisabreu
    9:41 am - 11-10-2008

    Hello.

    I haven”t taken a deep look at the way they do their analysis, but I”d expect that CodeContracts.Exists should let them to static analysis (possible only in some scenarios, of course) while the other option will only be able to give you runtime analysis. I”ll try to dig a little deeper and if I find anything I”ll put back my answer here.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>