Brendan Enrick

Daily Software Development

Try Writing Try Methods

When I say "Try Methods", I am of course referring to the common prefix "Try" on a method, which implies that the method is going to attempt to do what you're asking by using an output parameter for the operation and using the return value to indicate whether the attempt succeeded.

The common ones that people see in the .NET Framework are the TryParse methods, which attempt to parse something and if it can't be parse, they assign the default value to the output parameter and return false. If the succeed, the parsed value will be placed in the output parameter and the return value will be true. If the code failed, the convention is to use the type’s default value to assign to the output parameter. This lets you write code like this:

int someNumber;
int.TryParse(userInput, out someNumber);
// use the number entered or the default 0
int result = 1 + someNumber;

 

This is also great when you're going to be checking whether the method succeeded. In fact, you can use the try method directly in the if block, which usually makes things nice and clean. Here is an example of using them like that:

int someNumber;
if (int.TryParse(userInput, out someNumber))
{
    // Do something with someNumber
}
else
{
    // Invalid input: handle this case accordingly
}

 

Yes, you know all of this and have seen it before, however, are you writing these types of methods yourself or is your only experience with them the standard TryParse ones?

What I am trying to emphasize here is that you need to write your own Try methods in your code. You will thank yourself later.

Everyone can see the obvious benefit of not having to check for the default value to see if it the method worked. You also don't have to have ugly Try-Catch logic in your code. You get an if statement instead.

The real benefit of a writing a Try method has nothing to do with what I've already said. The most important benefit, in my opinion, is that you have a return value from it that isn't the value you are using for your logic. By having this return value for its success, you have to decide on how to handle the case where it failed.

There are important cases that might be forgotten, but having a return value means that I need to handle the return value. When I have it, I need to decide what to do with it. There may be a message I need to display to a user. There may be logging I need to do. I might be able to ignore that case. What is important, however, is that I thought about how to handle it. I had the chance to make sure that I handled the case correctly.

Create your own “Try” methods. I recommend looking into creating your own “TryParse”, “TryGet”, TryDelete”, and anything else that has a chance of failure that you may want to handle.

Common Reuse Principle

Classes that are used together are packaged together.

This is the April topic from 2011 NimblePros Software Craftsmanship Calendar, which includes a nice quote.

Common Reuse Principle (CRP):
Classes should be packaged together when reusing one will mean reusing them all. Source: “Agile Principles, Patterns, and Practices in C#”
by Robert C Martin

This is a pretty simple principle, and one that should seem quite logical. Not everyone agrees with the principle, but it least has a good point. If two things are going to be reused together, it makes logical sense that you should package them together.

Imagine if we didn’t follow this for ASP.NET and instead had everything spread around in some random assortment of assemblies. If I were accessing my HttpRequest, which is normally in the System.Web assembly and doing something with the cookies from that, which is an HttpCookieCollection. That HttpCookieCollection is a collection of HttpCookie. All of these are in System.Web, since they’re commonly used together. There is one assembly that we need to use this full set of classes.

Now think of how much fun this development experience would be if we had broken these apart such that the HttpRequest was in the System.Web assembly, HttpCookieCollection was in System.Web.Collections assembly, and HttpCookie was in the System.Web.State assembly. That would mean having to access three different assemblies to get three closely related classes.

Don’t get me wrong, I like having smaller, broken up dependencies, so that I don’t have to depend on a lot of things I don’t need. In fact, I have to have a good number of assemblies when I use the onion architecture. (They’re not all compile time dependencies everywhere they’re used though.)

The painful part, however, is when there are obvious pieces that should be together and aren’t. Common reuse is basically saying that there is pretty much no time that I would use HttpCookieCollection without also needing HttpCookie, so they should be in the same package. (Just those two from my example. I think that HttpRequest could be somewhere else with a good reason for it. Although we all know that all of these classes are in the same assembly right now.)

What’s your take on it? There is a lot of gray area with Common Reuse Principle.