I often find myself wondering what programming best practices apply to solo programming, since most of the time, I'm the only programmer on a project. I just started experimenting with C# 4.0 Code Contracts, and I thought I'd ask the community what utility they may have for a solo programmer.
Here's where I'm coming from with this. Most of the time, when I encounter an exception, it means there's a bug in my code. There are definite exceptions (no pun intended) to this, such as when I'm dealing with something external, such as a text file, database, or service, but for the most part, exceptions mean I did something wrong.
Take this simple method:
public void MapEntity(PersonModel model, PersonEntity entity)
{
entity.Name = model.Name;
entity.Age = model.Age;
entity.Updated = DateTime.Now;
}
If either model
or entity
are null, this method will throw a NullReferenceException
.
As the only consumer of my code, I know that I shouldn't pass in a null reference, but if I somehow do, I want an exception to be thrown, and I want the debugger to jump right to the source of the error so I can see what happened.
That said, I could write:
public void MapEntity(PersonModel model, PersonEntity entity)
{
Contract.Requires(model != null);
Contract.Requires(entity != null);
entity.Name = model.Name;
entity.Age = model.Age;
entity.Updated = DateTime.Now;
}
This has the advantage of explicitly indicating (to myself) that the two arguments are not allowed to be null. However, it's very unlikely I would make this mistake (because I know what the method does). Further, if I understand properly what Requires()
does, the behavior at runtime if a null argument is encountered would be pretty much the same. So, I can't help but wonder, what have I gained besides two lines of code?
As a counterpoint, here's a case where I see definite value in being explicit:
public User FindUser(string emailAddress)
{
if (string.IsNullOrWhiteSpace(emailAddress)) return null;
var users = DbContext.Users.Where(u => u.EmailAddress == emailAddress);
Contract.Assert(users.Count() <= 1,
"The database appears to be corrupted:
More than one user was found for the provided email address.
Email addresses are supposed to be unique.");
return users.SingleOrDefault();
}
But in this case, the reason I see value in using a coding contract is to indicate that something that has gone wrong that is not a bug per se (though it could have resulted from a bug elsewhere in the system).
I'd like to know if I'm on the right track with my thinking, or if there is more value in code contracts than I realize. Does it pay to use contracts when you can examine and debug the code yourself or only when the code is going to be used by a third party?