Scott Dorman

blog

  Home  |   Contact  |   Syndication    |   Login
  448 Posts | 9 Stories | 359 Comments | 55 Trackbacks

News


Post Categories

Image Galleries



Creative Commons License


Microsoft MVP


MCP Profile


Subscribers to this feed

Locations of visitors to this page

View blog authority

Add to Technorati Favorites

Windows Live Alerts

IM me

Get Free Shots from Snap.com

Community Credit Hall of Fame

Get Feedghost

Blog: Scott Dorman - Get your quick ping button at autopinger.com!

AddThis Social Bookmark Button

Xobni outlook add-in for your inbox

Windows Live Translator

Twitter












Tag Cloud


Article Categories

Archives

Post Categories

Image Galleries

Friday, July 04, 2008 #

My earlier post on the Null Object pattern led to a few critiques about the fact that I was presenting an extension method to do what is essentially a very simple logical test, and, as a result, doesn’t provide much value.

For reference, here is the original extension method from that post

public static class NullObjectExtenstions
{
    public static bool IsNull(this object source)
    {
        return (source == null);
    }
}

Yes, this is an extremely simple method and performs a very basic logical test. However, consider the static IsNullOrEmtpy function on String (taken from Reflector):

public static bool IsNullOrEmpty(string value)
{
    if (value != null)
    {
        return (value.Length == 0);
    }
    return true;
}

I would argue that this is a relatively simple method and performs two very basic logical tests. What is the benefit to using IsNullOrEmpty? In a word, consistency. By using IsNullOrEmpty, I know that every time I need to perform this test it is executing the exact same code in the same order. I don’t have to worry about someone accidentally testing “Length == 0” before the “!= null” and causing a NullReferenceExcpetion.

This same benefit applies to the IsNull extension method. It introduces that consistency (although I agree this test is still very trivial) for testing nullability. As I mentioned in my comments, the better choice for the extension method would probably have been an IsNotNull method. Here is a more complete NullObjectExtensions class:

public static class NullObjectExtenstions
{
    public static bool IsNull<T>(this T source) where T : class
    {
        return (source == null);
    }

    public static bool IsNotNull<T>(this T source) where T : class
    {
        return (source != null);
    }
}
Technorati Tags: ,

My post on the Null Object pattern has generated some interesting dialog. One of the trends that I have seen is the idea that defensive programming means your code should fail as early as possible. I couldn’t agree less.

According to Wikipedia,

Defensive programming is a form of defensive design intended to ensure the continuing function of a piece of software in spite of unforeseeable usage of said software. The idea can be viewed as reducing or eliminating the prospect of Murphy's Law having effect. Defensive programming techniques are used especially when a piece of software could be misused mischievously or inadvertently to catastrophic effect.

While this is a good definition, I think it still leaves much to be desired. The Wikipedia entry goes on to say that defensive programming is one approach to improving software quality by “Making the software behave in a predictable manner despite unexpected input or user actions.”

I think this is the closest definition that actually conveys what defensive programming is all about. The idea behind defensive programming is that the application should behave in a consistent and predictable manner even in the case of unexpected conditions.

There are a lot of different ways to achieve this and they are all different depending on what you are trying to accomplish with the code, the programming language, and the control structures being used. For example, considering a switch statement:

switch (Orientation)
{
   case Orientation.Horizontal:
      break;

   case Orientation.Vertical:
      break;
}

This is perfectly acceptable code, right? Remembering that enumerations are simply numeric (generally integer) values, it is entirely possible for this switch to get passed a numeric value that doesn’t correspond to either Horizontal or Vertical. In that case, there is the possibility of the switch, or code following the switch, to crash. One option to handle this would be to add a default case to the switch:

switch (Orientation)
{
    case Orientation.Horizontal:
        break;

    case Orientation.Vertical:
        break;

    default:
        break;
}

In the default case you could throw an exception (if that’s the appropriate behavior) or, more likely, you take some action that ensures either the remaining code doesn’t execute or at least doesn’t crash.

Looking at another example, this time casting, shows some other ways to program defensively. A common scenario for casting is in UI programming and handling events.

private void button1_Click(object sender, EventArgs e)
{
    ((Button)sender).Text = "You pressed a button";
}

Again, this code looks perfectly reasonable and will work just fine until someone accidentally assigns this event handler to something other than a button. Once that happens, the code will crash since sender won’t be castable to a Button. There are several different ways to handle this but the simplest (at least in my opinion) is

private void button1_Click(object sender, EventArgs e)
{
    Button button = sender as Button;
    if (button != null)
    {
        button.Text = "You pressed a button";
    }
}

Yes, it is a bit more code but it also guarantees that no matter what happens if the object that raised the event is not a Button, the code won’t crash. You could have chosen to throw an exception (or just let the exception generated by the runtime bubble up the call stack until it’s handled, but that may not be desirable depending on what you are doing.

The bottom line is that catching exceptions (not throwing them, but catching them…and all exceptions will eventually be caught, but possibly not in a way you intended) is expensive and if there are techniques that allow your program to continue functioning properly or otherwise gracefully handle exceptional conditions, known as “defensive programming”, you should opt for that approach.

Technorati Tags: ,

Tuesday, June 24, 2008 #

Just a reminder that the Tampa Bay IASA June meeting is this Thursday night (June 26th) starting at 6:30 PM.

Please be sure to register so we have an idea of how many pizzas to order, and remember that the outside doors lock and the elevators need a security key after 7:00 PM. Don't forget to sign up for our free newsletter!

 

Dependency Injection using the Microsoft Unity Application Block
The Microsoft Unity Application Block is a lightweight Dependency Injection Container that is currently being incorporated into the latest releases of Enterprise Library and the Composite Application Library (Prism). This session will be a brief introduction to Dependency Injection and Inversion of Control concepts and an overview of how use the Unity Application Block to build loosely coupled applications.

Speaker: Randy Patterson has spent over 15 years as a software developer and is currently working for Catapult Systems as a Senior Lead Consultant. He has spoken at several Code Camps and Users Groups throughout Florida. He also started the Tampa .NET Users group in 2000 when .NET was in beta and is currently helping to start the International Association of Software Architects, Tampa Chapter.

When & Where:
Thursday, June 26, 2008 from 06:30 PM - 08:30 PM (ET)
Microsoft Corporation
3000 Bayport Drive
Suite 480
Tampa, FL 33607

View a map
View 1-Click Directions

Technorati Tags: ,

Monday, June 16, 2008 #

community-champs-badge2If you are a user group leader in the worldwide community of Microsoft® .NET user groups, you probably already know about INETA. Don’t know about INETA? Then you should definitely take a look and become an INETA member group.

Are you already involved with an INETA member group? Be sure to check out the new Community Champions program. This is just one of the ways INETA recognizes and rewards those who contribute to the user group community and help it grow.

The Champs program was specifically designed to help recognize what it takes (and provide a little bit more insight for those that aren’t involved) to run a successful user group community by giving you a way to record all of those tasks. In exchange for taking a few minutes to record your tasks, you become eligible for a quarterly Community Champions Award.

The Community Champions Award lasts for 12 months and offers a letter of commendation and certificate of achievement from INETA, recognition on the INETA website, and a few great prizes like an MSDN Subscription or an Xbox 360.

If you have anything to do with helping to run a user group, be sure to check it out and start submitting your tasks today. The first award period is coming up, so you might be one of the first people to win. Right now the INETA Community Champions program is only available to user groups in North America, but the Champs team is going to be working on international launches soon.

 

Technorati Tags: ,

 

 

kick it on DotNetKicks.com Digg!

 


If you write .NET code using Visual Studio 2005 or 2008, you’ve probably noticed the automatic outlining the IDE makes available to you. This automatically creates collapsible sections in your code for comments, regions, functions, properties, namespaces, classes, and the using block.

image

While this is a great feature and one that I use on a daily basis, it would be great if this extended to automatically outlining control structures, such as if/then, while loops, for/foreach loops, try/catch blocks, etc.

The purists out there might argue that if you need this collapsibility then your code is too long…and they are probably right. However, the purist point of view is not always a pragmatic one. There are numerous times where being able to collapse a long try/catch block or a large case statement would have been very helpful.

If you want to see this feature added to an upcoming release of Visual Studio, be sure to vote for the feature request on Microsoft Connect.