Lets start with our AddRange function from last time.
Functionally this works, but what happens if target or source is null? You get a NullReferenceException without any clue as to which argument is messed up.
And of course you don’t want to try adding items to a read-only collection.
So far so good. But those rules are a little soft and there is nothing to enforce them at compile time. To fix that, we can add some Code Contracts support. By enabling Code Contracts, developers using Team System will get compiler warnings when they try to break a rule. (Developers not using Team System will just get the usual runtime exceptions.) So now we have this:
Right now we are making three demands: Source cannot be null, target cannot be null, and target cannot be read-only. But we aren’t making any promises, this code could literally do anything and still obey the contract. Wouldn’t it be nice if we could promise something, like say the target.Count would be incremented correctly? Such as example might look like this.
In order to make this promise the source cannot just be an enumerable, it must be a collection with a pre-defined size. Looks good, too bad it doesn’t work. According to the compiler, line 6 cannot be proven. It appears, though I’m not certain, that we currently don’t have a contract that says “For all ICollection<T>, calling Add will increment Count by 1.” And without that contract, our code can’t make any promises.
Design by contract is hard. Retrofitting design by contract onto a system that never before had it is downright painful.