My musings about .NET and what not

Should We Return Null From Our Methods?

I read a interesting article recently about the potential perils of Null Check Hell. The author’s suggestion? Stop allowing any of your methods to return null, ever. No nulls returned, no null checks necessary. Problem solved, right?


No Nulls

Abby Fitchner is a self-described “hacker chick, software engineer, and ScrumMaster Extraordinare” from New Hampshire. Being a born-and-bred New Englander myself (Portland, Maine) who sometimes feels out of place here in the Midwest, I have a soft spot for the Red Sox, whoopie pies, Moxie, and gerdy bloggers from back East.

That graphic to the right? I kifed it right off her blog (being from New England, she’ll know exactly what that means).

Anyway, this post if not really about Abby, but about an interesting idea she proposes in a recent blog post of hers. To paraphrase:

I can't help but feel my code is getting harder and harder to read as I wade through an ever increasing number of if != null checks before finding my way to the real logic that I actually care about...

Doesn't it feel like there has to be a better way?!
Well, actually yes, there is.
Stop allowing any of your methods to return nulls.
EVER.
No nulls returned, no null checks necessary. Thank you for reading.

Wow, what a revolutionary idea. What would you give to never have to look at one of these cursed things again?

 Then I thought about this a little further. I’m wondering, is this possible? Or necessary? Or even… desirable?

Let’s step back for a minute and consider the case in which a method is expected to return something, yet for some reason it cannot return a valid result (assume we’re talking about a reference type here). As I see it, unless I’m missing the boat, there are three distinct possibilities. The method can:

  1. Throw an exception.
  2. Return an empty “default” instance of the object.
  3. Return null.

In her blog post, Abby proposes the second option:

Of course, even after all of this cleaning, we'll still have some methods that just want to return null. But, even so, a lot we can handle by simply returning an empty instance of the object or collection where we previously would have returned null.

Let’s nail this down to earth with a concrete example. Consider the .NET Membership.GetUser(string userName) method. If a user with the name of userName is not found in the data store, what should this method do? What behavior should a programmer using this framework reasonably expect? In other words, what is the most meaningful outcome?

Option 1: Throw an exception

Okay, for the purposes of this little thought-experiment, pretend you are Scott Guthrie (I do this all the time) and that you are responsible for writing the code to implement Membership.GetUser. Perhaps your first inclination is to throw an exception. You really want to call it ComeOnThatUserIsSoNotHereException, but wisely opt instead to call it MembershipUserNotFoundException.

But then you think, “Hmmm… is throwing an exception really the best way to go here?” When considering throwing an exception from a method, there is one question you need to ask yourself:

Is the condition that causes the proposed exception truly exceptional?

Throwing an exception is acceptable when a method cannot provide its defined functionality. However, if a given condition could happen naturally in the course of a function’s normal operation, then you shouldn’t throw an exception in response to it.

In our example case, you asked the method to find a user with a given user name. It looked, and it didn’t find that user. That the method failed to find the user is due to the fact that the user does not exist, not because the method couldn’t provide its normal function. In fact, the method performed perfectly well! Therefore, throwing an exception simply doesn’t make sense in this case.

Option 2: Return an empty instance

What exactly would an “empty” instance of MembershipUser look like? Most of the properties of this class are simple types like dates, booleans, and strings. So, an empty instance of MembershipUser would presumably provide string.Empty for the string properties,  DateTime.MinValue for date properties, false for booleans, and Guid.Empty for the ProviderUserKey. (How the method would “guess” which of your membership providers you intended to use would be a pretty sticky problem, but let’s ignore that issue for now.)

Now, let’s use this functionality in very simple administrative function – changing a user’s email address.

protected void btnChangeEmail_Click(object sender, EventArgs e)
{
   MembershipUser user = Membership.GetUser(txtUsername.Text);

   // if the user was not found, user would be an "empty" instance
   user.Email = txtEmail.Text;

   Membership.UpdateUser(user);
}

I probably don’t have to tell you what’s wrong with this picture. The user’s intent in invoking this method is to work with the user who’s name is the value contained in txtUsername.Text. If there is no such user, the method simple provides us with an “empty” user, which is clearly not the caller’s intent at all. We’re not interested in working with some meaningless empty user, but of course, the method has no way of knowing this, and proceeds merrily along its way. Naturally this user doesn’t exist in the data store, so when the UpdateUser method is called, the whole thing flops like a pancake. Whoops! Looks like we’re going to have to check for that.

protected void btnChangeEmail_Click(object sender, EventArgs e)
{
   MembershipUser user = Membership.GetUser(txtUsername.Text);

   // if the user was not found, user would be an "empty" instance
   if (user.UserName != string.Empty)
   {
      user.Email = txtEmail.Text;
      Membership.UpdateUser(user);
   }
}

As you can see, we certainly haven’t saved ourselves any work here. Sure, we’re not checking for null, but in this case we still have to check for empty. This example points out the problem with the “empty instance” approach: in many cases, working with an empty instance of an object is just as logically invalid as attempting to use a null reference. This means you still have to perform the requisite checks, which is what you were trying to avoid in the first place.

Option 3: Return null

At this point, perhaps it would be helpful to stop and think about exactly what we mean by the concept of null.

Take a look at the NullReferenceException message in that all-too-familiar screenshot above: Object reference not set to an instance of an object. The means, quite literally, that you have attempted to refer to an object for which a reference does not exist. Move along folks, nothing to see here. There is no object to refer to. So, to say that a variable is “null” is to say that it does not refer to any object.

This is exactly why the Membership.GetUser method returns null when the user is not found in the data store. The method is telling us, “I tried to do as you asked, but I came up empty-handed. That user does not exist. There is no user object for me to return.”

When the object that is meant to be returned by a method does not exist, returning null is the only semantically meaningful thing you can do.

We’re not talking about cases where the argument supplied to the GetUser method is null, or isn’t a valid username, or the provider can’t connect to the database. All of those conditions throw exceptions, because in these cases the GetUser function cannot complete. But in the case where the function does complete, yet still cannot return the intended value, returning null is exactly the right thing to do.

protected void btnChangeEmail_Click(object sender, EventArgs e)
{
   MembershipUser user = Membership.GetUser(txtUsername.Text);

   if (user != null)
   {
      user.Email = txtEmail.Text;
      Membership.UpdateUser(user);
   }
}

Summary

Never, ever returning nulls from your methods will definitely alleviate the need for null checking; in much the same way that toe fungus can be prevented by removing your toes. But both cases represent an extreme solution that probably isn’t the wisest course of action.

If you find yourself writing a seemingly endless stream of null checks in a given method, you can use refactoring to abstract them away, which can make your methods easier to read. Amy shows some clever examples of this on her blog.

In my opinion, the best thing you can do to mitigate the pain of null checking is to properly and copiously document your methods. The .NET Framework uses XML documentation to clearly indicate if and when a method can return null, and you should do the same. This allows the documentation to show up directly in Intellisense (if you’re using the Visual Studio IDE), which informs the developers on your team exactly when and where null checks are necessary, and when they aren’t. This goes a long way toward alleviating “null check paranoia”, and keeps the dreaded NullReferenceException from biting you in the keyster at runtime.

Subscribe to this blog for more cool content like this!

kick it on DotNetKicks.com

shout it on DotNetShoutOut.com

vote it on WebDevVote.com

Bookmark / Share

    » Similar Posts

    1. Defensive Programming, or Why Exception Handling Is Like Car Insurance
    2. Integrating Exception Handling Into the Development Cycle
    3. If At First You Don’t Succeed - Retrying Mail Operations in .NET

    » Trackbacks & Pingbacks

    1. You've been kicked (a good thing) - Trackback from DotNetKicks.com

      Should We Return Null From Our Methods? — June 5, 2009 5:58 PM
    2. Thank you for submitting this cool story - Trackback from DotNetShoutout

      Should We Return Null From Our Methods? — June 7, 2009 1:18 PM
    3. Pingback from Arjan`s World » LINKBLOG for June 7, 2009

      Arjan`s World » LINKBLOG for June 7, 2009 — June 7, 2009 2:05 PM
    Trackback link for this post:
    http://leedumond.com/trackback.ashx?id=65

    » Comments

    1. abby, the hacker chick blog avatar

      hahaha, okay, this is a trip and thank you SO much for such a thoughtful response. wow!

      I have to say that since I wrote that blog post a whole 6 months ago, I have rather changed my mind on the notion of returning an empty object. So, I agree with you there, not big on returning en empty objct.

      But, I have to say since then I've actually been leaning towards throwing an exception. I do understand your arguments, but I'm trying to think about it from the perspective of the caller. And, as the caller of this method, would I rather have to litter my code with if != null checks? Or just put it all in one big try/catch block and just deal with the exceptions at the bottom?

      Now, a totally OTHER idea - which was also very kindly pointed out by a couple readers of post in question is to use the NullObject pattern from Martin Fowler's book, Refactoring. If you have the book, see pp 260-261.

      The idea came from Ron Jeffries, he had to call this method on an object to do something, but he was forever having to 1st check if the object was null, which was muddying up the code. So, to get around this he created a subclass of the object in order to represent null instances of it. That subclass then overrode the method in question to do whatever behavior was appropriate to take place if the object was null (perhaps no op, but maybe it would log a message or something). Eventually, he wound up overriding several methods to do the appropriate action when the object was null.

      While I like this notion, it feels like a lot of work, especially when you're working from a huge code base. So I haven't tried it yet.

      Oh my gosh, I'm sorry this is so long! But, thank you ever so kindly for this! Very cool. :-) Consider me CRM'ed.

      abby, the hacker chick blog — June 5, 2009 7:06 PM
    2. Paulo Koch avatar

      If the method is named "GetUser", it's only purpose is to get the user. Not getting the User you asked for is not an option. Therefore, not having the right one to get makes it impossible to behaves as asked. Hence, you must engage in "not expected" behavior, exceptional behaviour. This is an exception to me. Should the name be TryGetUser, null would be a perfectly expectable return value.

      I think this follows exactly the same reasoning as throwing an exception when you try to open a file that can't be found.

      Another note I would like to make is that "refer to something that does not exist" != "it does not refer to any object" != "There is no object to refer to". But now I'm just being a nazi. =P

      Paulo Koch — June 6, 2009 9:25 PM
    3. Lee Dumond avatar

      @Paulo - The point I was trying to make was that a user not existing is not an indication that the GetUser method failed; in fact, just the opposite. If the argument is valid and understood and the connection to the datastore is successfully made, to me that means the method did its job. Not finding a user that isn't there to find is neither indicative of a malfunction of the method itself nor its ability to complete its mission.

      I have to disagree with your assertion that this situation is analogous to attempting to open a file, since the File.Open method returns a filestream, and there is not much semantic value in returning a null filestream. Given that however, I do see your point, and it's a valid one.

      Lee Dumond — June 6, 2009 10:05 PM
    4. Victor avatar

      Lee Dumond, I fully agree with you:

      if there is NO user with passed username, you should get NULL....

      Victor — June 7, 2009 12:46 AM
    5. Mohamed El-Beltagy avatar

      @Lee - I totally agree with you. A method can:

      1. Throw an exception.

      2. Return an empty “default” instance of the object.

      3. Return null.

      But it's not a matter of should/shouldn't return null.

      It's a matter of 'when to use what'. Each has it's cases. But actually, there is a one common factor that decides the 'when to use what', it's the business required.

      I know that most likely you already know what I will say, but let's consider these examples:

      1. Throwing exception: when you try to open a file, which the business mandates it. The program has no more business to do, no need to check for nulls or not. Just throw an exception and let be handled by the framework you are using to the GUI (web or desktop).

      2- Empty objects: IMHO, I think that this case is mostly applicable for simple objects. I mean, if the method returns a String or something, not complete object. Of course, in some cases it is applicable. But it really depends on the business.

      3- Null: as you mentioned in your example, the user object cannot be returned empty. We have not done a thing. On the contrary, we may have increased the work. Consider this example:

      MembershipUser user = Membership.GetUser(txtUsername.Text);

      // if the user was not found, user would be an "empty" instance

      if (user.UserName != string.Empty && user.age != string.Empty) {

      user.Email = txtEmail.Text;

      Membership.UpdateUser(user);

      }

      What if we have more conditions? How you will handle the else? Is it going to be if..else_if..else conditions?

      Return null is perfect in this case. Check for null and then do you business.

      Thank you for your time reading my reply. Hope my point is clear. There is no exact 'correct' option. It all depends on the business required and a particular case you have.

      Mohamed El-Beltagy — June 7, 2009 3:18 AM
    6. Joe Enos avatar

      In my code, any method returning a single object can return null if the scenario is possible. Any method returning a collection of objects never returns null - if nothing is found, it returns an empty collection, so iterating through the results doesn't require a null-check.

      This strategy has worked well for me - null checking is needed, but if we didn't have null checking, we'd still need to wrap the call in a try/catch or check for the "empty" object - so it seems like null checking is the most reasonable course of action.

      Joe Enos — June 7, 2009 3:30 AM
    7. Nikola Malovic avatar

      In cases of not existing result my code returns null when a class is returning type and returns empty collection when a collection is returning type.

      IMHO, raising an exception is not a good solution at all from both performance and API discoverability point of views.

      What is the advantage of catching exception VS checking if a result is null?

      In both cases, if I forget about it I would have exception occuring.

      Nikola Malovic — June 7, 2009 3:54 AM
    8. bob avatar

      This is obvious. Somer user action invoked change email. If that user does not exist you have an explicit transaction failure due to non atomic behavior.

      eg the session is invalid or the database has changed before this action could be properly invoked.

      Throwing an exception is THE ONLY proper course of action.

      Dont be a newb.

      bob — June 7, 2009 4:08 AM
    9. matt hinze avatar

      Check out C# code contracts

      www.infoq.com/.../Code-Contracts

      matt hinze — June 7, 2009 6:56 AM
    10. Dennis Sellinger avatar

      When dealing with a similar issue in Collection indexers, the .NET framework provides a get indexer which throws when the item does not exist and a TryGet method that uses an out parameter and returns a bool indicating whether or not the get was successful. I think if you are simply implementing a getter this idiom is preferable and I use it.

      When you are not implementing a getter you, should look at the semantics of your method and determine the best course to follow from there. Neat and tidy rules are almost never universally applicable.

      Dennis Sellinger — June 7, 2009 8:09 AM
    11. sboulay avatar

      interesting article. Now lets throw in a GetById where Id is the primary key that you are trying to find. Should we return null or an exception. In this case, I would say exception since you are expecting that object to be there although I have also used null in the past. What do you guys do?

      sboulay — June 7, 2009 10:14 AM
    12. Peter avatar

      Great idea!

      Option 4: use a different pattern!

      Either you could do

      while(true) {

      Object obj = iterator.next();

      if(obj == null)

      break;

      }

      Or you can do it without returning null:

      while(iterator.hasNext()) {

      Object obj = iterator.next();

      }

      In the case of the findByName(string) you have to introduce a separate 'checkFindByName' method to prevent us from the != null check. I think it is cleaner, but sometimes a little bit overhead to introduce a separate method for every method.

      So, in theory the No.NPE.AnyMore is possible.

      But the two problems in praxis are that too much libraries are out which do not behave in this manner.

      And even for my Option 4: this sometimes too much overhead.

      Peter — June 7, 2009 10:36 AM
    13. Peter avatar

      Or instead of introducing a new method you can return a none null object of class Result. And this class adds specific methods like 'boolean wasSearchSuccessfull()'.

      But I think is the same: too much overhead; only sometimes good...

      Peter — June 7, 2009 10:42 AM
    14. Lee Dumond avatar

      @bob - User does not exist does not indicate a transaction failure. What about the case where the userName was simply misspelled?

      And BTW, are you calling Scott Guthrie a newb? ;-)

      Lee Dumond — June 7, 2009 10:55 AM
    15. Lee Dumond avatar

      @Dennis - I am a big fan of the X - TryX pattern and write about it in my Robust ASP.NET Exception Handling book. The .NET Framework uses it extensively with the parsing of value types. I was gonna include it here but I don't think it applies as well to reference types.

      Lee Dumond — June 7, 2009 11:02 AM
    16. Lexandro avatar

      My solution is to returning "null" objects is adding a non-persistent field to the object. Called null. I had created isNull/setNull methods and I'm ALWAYS creating this type of objects with factory methods.

      getInstance() and getNullInstance().

      With these steps I can easily create/check the "null" state of the object and reuse it if required.

      Lexandro — June 7, 2009 4:53 PM
    17. Ben avatar

      @Abby

      Fowler and Jeffries did not invest the NullObject pattern. The first documented version came from Bobby Wolf, who noted known usages. As with most patterns, they are rediscovered countless times.

      I personally love the NullObject pattern to allow easy disablement of a feature. For example, to disable a cache in a library would be to inject in a null hashmap as the data store. If an event listener can be registered, a null listener is simpler than a null-check. For cases where the application doesn't doesn't seemingly change based on whether a null instance is used, its perfect. It allows a lot simpler code by disablement of features via polymorphism.

      I prefer to use null values and exceptions carefully. I don't like having many try/catch blocks, but try/finally is great. I like to spread assertions liberally and fail hard when possible. I don't like using exceptions when a failure is likely, such as to parse a string into an integer. I'd rather receive a null value than needlessly build the stacktrace if all the exception tells me is that the input isn't a number. I can handle it gracefully if expected, or assert it myself if unexpected.

      I agree with your premise, though. Null is often abused. Even worse, we build layers of checks to work around the abuse rather than force the bad code to be fixed. Sometimes we need to stand our ground and make others fix their code rather than corrupting ours!

      Ben — June 7, 2009 8:57 PM
    18. Lee Dumond avatar

      @Ben

      >> I'd rather receive a null value than needlessly build the stacktrace if all the exception tells me is that the input isn't a number.

      Not sure how a method is going to return a null integer. ;-)

      I think the TryParse methods in the .NET framework handle this pretty nicely. You get *both* a boolean indicating success/failure, *and* the parse result (or a default value, 0 in the case of an integer) as an out parameter.

      Lee Dumond — June 7, 2009 9:29 PM
    19. centribumble avatar

      EMPTY VALUES: In many cases the empty value has a semantically different meaning to the null value. If I ask you for a pitcher of beer and you pass me an empty glass, then that means you have run out of beer. If you pass me nothing at all, then perhaps you have run out of pitchers as well. There is a difference in meaning, and so therefore the one should not be substituted for the other.

      EXCEPTIONS: The problem with @bob's reasoning is that, in his case, the Membership.GetUser enforces all these preconditions on the scenario in which it is called, which doesn't make it a particularly useful or powerful method. Ideally, we want Membership.GetUser to not really care when or how it is called. Membership.GetUser should just do the job that its been asked to do and that's it. If Membership.GetUser can't find a user, then why should it have the audacity to start making assumptions about my system? As Lee said, there are many perfectly valid reasons for calling GetUser with an incorrect username.

      NULL PATTERN: To me this seriously over complicates the situation. We are trying to simplify things for ourselves by removing the need for null checks. The null pattern, and use of factory methods like GetNullInstances, whilst they do have their uses, are serious overkill that makes code harder to read and use.

      centribumble — June 7, 2009 9:30 PM
    20. Lee Dumond avatar

      @centribumble - GREAT comment. I think you (and Dennis) actually got what I meant by "semantically meaningful".

      Lee Dumond — June 7, 2009 9:53 PM
    21. Adelle Hartley avatar

      I find the Null object pattern useful for reporting or otherwise displaying read-only data, because I can bind directly to a property of a null instance.

      I like the idea of having separate X and TryX methods and may end up using that pattern henceforth alongside a consistently named null-object-returning method. However, I can see how it would be a lot of work for hand-coded methods. It would be nice to see the X/TryX idiom turn into a language feature (OT: I'd like to see Ruby's DoIt/DoIt! idiom as a language feature too (methods which modify an object in-place are often named with a ! with a non-exclamatory version that performs the action on and returns a new instance)).

      I like Try/TryX because it means the api author doesn't have to second guess how the library will be used. If you don't need to be all things to all people, (eg, because you're both the author and primary user of the library) then I'd just pick one and stick with it. In that case I lean towards returning null.

      Null checks don't have to be that onerous. I find it is usually correct for the caller to throw an exception (or return null) and in any case, the "main logic" should not be nested within several conditional clauses, and needn't be, if you exit the routine early for the null cases.

      Adelle Hartley — June 8, 2009 3:42 AM
    22. Mario Gleichmann avatar

      Another 'option' (if you're not bound to .Net): take a look at Haskells or Scalas 'Option' Monad ...

      Greetings

      Mario

      Mario Gleichmann — June 8, 2009 7:11 AM
    23. dan avatar

      It seems to me that returning null is the equivalent of wrapping two methods (UserExists + GetUser) into one.

      This has the advantage of brevity but it forces you to call both 'methods' even though you may only want one.

      Personally I prefer my functions to do one thing and do it well.

      e.g.

      if (IsInt(TextBox1.Text))

      intValue = Int.Parse(TextBox1.Text)

      dan — June 8, 2009 7:33 AM
    24. Yngve Nilsen avatar

      @abby

      "But, I have to say since then I've actually been leaning towards throwing an exception. I do understand your arguments, but I'm trying to think about it from the perspective of the caller. And, as the caller of this method, would I rather have to litter my code with if != null checks? Or just put it all in one big try/catch block and just deal with the exceptions at the bottom?"

      ---------------

      But, Abby, what do you do if the null-return isn't actually an exceptional response? Maybe you actually expect it to return null in some cases, and carry on with your method. This would require you to have several try..catch'es in your methods, which to me is messy :)

      I'd rather do a simple

      var user = membership.GetUser(email);

      if(user != null)

      {

      do whatever you need to do

      }

      else

      {

      // redirect user to the register/invalid username-part of our site

      }

      Of course, having try catch around this is also valid, but ONLY in the cases of having to recover from exceptional cases, like database-failure, network failure and so on. :)

      Interesting discussion, and great blogpost! :)

      rgds

      Yngve

      Yngve Nilsen — June 8, 2009 8:00 AM
    25. Steve Goguen avatar

      As Mario have pointed, you can always look to Haskell, F#, and LINQ for inspiration by considering using a monad, which got me to thinking: Why not create a nullable type that supports the IEnumerable in its most basic form, like a Maybe(Of User). You can define the conversion operators so that values can automatically lift like Nullable objects, but because a Maybe implements the IEnumerable interface, you could write elegent LINQ code that automatically propagates NULLs and terminates subsequent actions that rely on null values.

      Just a thought.

      Steve Goguen — June 8, 2009 10:46 AM
    26. Richard Minerich avatar

      This is why all .NET languages, not just F#, should support Union types and force all cases to be handled.

      Richard Minerich — June 8, 2009 11:25 AM
    27. Adam Toth avatar

      Great thread, and a tough subject.

      If the GetUser() method could possibly throw or bubble up an exception for things out of its control (like a database connection error), then it should return a MemberNotFoundException, since the caller should already have a try-catch around the call to deal with database connection failures.

      This way, callers don't have to write the try-catch AND the null check.

      If your code did not know for sure whether a user existed or not, then it should probably first do a UserExists call or a TryGetUser() type of implementation. If your code expected a user to be there, and called the GetUser method and nothing was found, then something bad happened and the rug got pulled out from under you (user was possibly deleted by someone else). Since it's totally possible that a user gets deleted between the time that a UserExists call is made and GetUser is called, it seems best to throw the MemberNotFoundException.

      In that particular case, null could potentially mean "The user never existed" or it could mean "The user was just recently deleted". When looking back at code from six months ago, I'd rather not have to figure out what exactly null meant in that instance.

      Adam Toth — June 8, 2009 3:29 PM
    28. Rob Packwood avatar

      Doesn't the experimental Spec # allow for non-nullable parameters and result type definitions?

      I think the syntax is something like this:

      object! GetSomeObjectByName(string! name);

      I kind of wish C# had some kind of implementation of this where something could identify a type to be never null, like the "!" in the example above. So "?" = sometimes null on a value type, and "!" = never null on a reference type.

      Think of all the extra validation the compiler could do for you versus all of the manual labor we always need to do with redundant null checking "just in case"...

      Rob Packwood — June 8, 2009 4:14 PM
    29. James White avatar

      I just started using a "ResultFact" return from non-trivial methods that has an IsGood, Message, and optionally a generic Content property. That way I can return a common object from all these methods and communicate both the result and any details back to the caller without lapsing into using Exceptions for non-exceptional cases. I'm not sure if this will prove out over the long term, but it almost feels like it should be part of the framework (sort of like tuple but in context)

      public class ResultFact

      {

      public bool IsGood { get; set; }

      public string Message { get; set; }

      public ResultFact()

      {

      }

      public ResultFact(bool isGood, string message)

      {

      IsGood = isGood;

      Message = message;

      }

      public ResultFact WithError(string error)

      {

      IsGood = false;

      Message = error;

      return this;

      }

      }

      public sealed class ResultFact : ResultFact

      {

      public T1 Content { get; private set; }

      public ResultFact():

      base()

      {

      }

      public ResultFact(bool isGood, string message) :

      base(isGood, message)

      {

      }

      public new ResultFact WithError( string error )

      {

      IsGood = false;

      Message = error;

      return this;

      }

      public ResultFact WithContent( T1 content )

      {

      IsGood = true;

      Content = content;

      return this;

      }

      public ResultFact WithContent( T1 content, string message )

      {

      IsGood = true;

      Content = content;

      Message = message;

      return this;

      }

      }

      James White — June 10, 2009 9:32 AM
    30. abby, the hacker chick blog avatar

      wow, what an awesome discussion, a lot of really great points!

      @Ben thank you for the history and the explanation, that makes more sense to me then what I'd remembered from the book on how you'd actually use it (which, I think is in a more limited manner, not for EVERY object).

      @Yngve I guess I'm not convinced that it's not exceptional. Although, I admit I didn't just publish a book exceptions! So I'm quite sure I'm not the expert on them.

      I will just leave you all with one more thing to think about. I was inspired to write that post at least in part from the book Clean Code by Robert Martin. In his Error Handling chapter, he talks about how most code is so dominated by error handling that it is difficult to understand & maintain. So here is his advice on the matter...

      "Don't Return Null. ...When we return null, we are essentially creating work for ourselves and foisting problems upon our callers... If you are tempted to return null from a method, consider throwing an exception or returning a SPECIAL CASE object instead." (p. 110).

      (I assume by SPECIAL CASE he's referring to something like the NullObject pattern.)

      abby, the hacker chick blog — June 10, 2009 5:12 PM
    31. Lee Dumond avatar

      Interesting that Robert Martin's "cure" for excessive exception handling is to throw an exception. ;)

      I think this just shows how long it's been since Mr. Martin has been down slogging in the trenches with the rest of us.

      Lee Dumond — June 12, 2009 12:19 PM
    32. abby, the hacker chick blog avatar

      ohhhh, do not criticize the Uncle Bob!!

      :-)

      abby, the hacker chick blog — June 12, 2009 5:10 PM
    33. Gerardo avatar

      Hi I want to add my $.02 to this discussion... and going to add something that I do which is similar to J. White's solution.

      I have an Enum (i.e. for a DAO class) which contains DataAccessReturnCodes valid for that class... something like

      UserDARC{

      OK,

      NotFound,

      AlreadyExists,

      NotVerified,

      Unknown

      }

      and then I will put the user object as an out parameter in the method being called.

      What I like is that I can quickly check for DataAccessReturnCode.OK in the same style you use for a dialog in winforms and proceed to use the object or show a message (interpret the return code). it seems like a lot of work, but i feel a lot of security that my code is behaving really well :)

      thanks for the discussion!

      G-

      Gerardo — July 20, 2009 3:09 PM
    34. Josh (pro membership blueprints) avatar

      Programming so often has these trade-offs. It's an interesting discussion. I too hate having extraneous code at every corner, but sometimes it's just easier.

      Josh (pro membership blueprints) — August 4, 2009 11:11 PM
    35. Stuie avatar

      Thanks for this article. I was having a moment of indecicive flopping, this was the perfect article to sort that out.

      Essentially I had a similar method, getMyRecord( myRecordIdentifier ) -> MyRecordClass example and flopped around between should it return null a blank object of the prescribed type or throw an exception.

      It is perfectly legal for it to not return a record if through its normal operation such record does not exist. In my opinion empty instances of objects are vaguely quantifiable at best and seems to just sugar coat a null object. Throwing an exception seemed too heavy handed when it is feasable and somewhat expected that something will try to get a record that does not exist. The null object describes the result perfectly. Fear not the null but your fear of the null.

      That said there is a time and a place for the other methods of handling similar but different situations, if for example you call something where it should always get a value say for example User.getLoginName() but the value has not been set (weak example I know), there is a strong case for an exception in that circumstance. Wear the glove that fits... or shoe, jockstrap... whatever.

      Stuie — February 19, 2010 7:54 PM
    36. name avatar

      Perhaps there's some context behind this argument that I'm not privy too, but if the suggestion to not use NULL is as generic (that is, applicable from a practical standpoint and is not bound to implementation specifics) as I'm reading it to be... I don't know, I find that rather strange; wouldn't that advice also depend on other factors as well, such as the library, API, or general environment your methods are being put into? Clearly speaking, if NULL is okay in the library or API you're using, then I'm pretty sure it's okay to return NULL. Perhaps this is so obvious that it hasn't been said. Irregardless, I didn't see too much in the way of justifying NULL as a proponent for consistency in the entirety of one's code, not just one's codebase. For example, the DirectX API has several methods that accept NULL as a parameter. It would be very strange to avoid returning NULL if it was completely okay (and desirable in some cases) in such a situation.

      Again, maybe I'm missing the context.

      name — December 2, 2010 12:53 AM
    37. Puzsol avatar

      For all the people who would prefer an exception to a null object, then simply don't put in the test for a null return and you will get one that you can catch!

      protected void btnChangeEmail_Click(object sender, EventArgs e)

      {

      try

      {

      MembershipUser user = Membership.GetUser(txtUsername.Text);

      user.Email = txtEmail.Text;

      Membership.UpdateUser(user);

      }

      catch (Exception ex)

      {

      // Do something useful...?

      }

      }

      If user is null, then you get the exception that you craved from the GetUser function call. The only difference is which exception will be caught... and then you have to inspect the exception to see what caused it, when any reasonable person might have expected that we might not be able to find the user.

      And as for the thought of just having a catch at the end of all the code... without any concern for what might go wrong and providing a logical path for that situation... I cringe, and would hate to be the next one to maintain that. I've seen some code like that and it ends up being more complicated (almost duplicating the function logic while trying to handle it) than if we were expecting the unexpected in the first place and handling the situation where it happened.

      And as for the NullObject...oh my goodness.. why would you do it? Because someone using your function might not handle it properly? Well they might not handle the NullObject properly either.... Consider this situation:

      Room r = myBookingSystem.bookRoom(people, from, to);

      SendEmail("Congratualtions, We have confirmed your room " + r.RoomNumber + " at my holiday spot for " + people + " people from " + from + " to " + to + ". ";

      If r is a null object, then the message still tells them congrats, they turn up, and there is no reservation... don't you hate that? Of course in this situation returning null or throwing an exception in the bookRoom function would stop this - one by forcing an exception to be caught, the other by providing the information that the booking failed (null) and more importantly not allowing the calling code to carry on as if the booking were successful.

      While handling null can be a bit of a pain sometimes, but I much prefer it to the alternatives and will continue to return null where appropriate.

      Puzsol — February 10, 2011 8:32 PM

    » Leave a Comment