Break the Habit : Nested If Statements

It is time to break some bad habits, and today we take some code written by a man I like (but who will remain nameless and linkless) that is in desperate need of refactoring. But this problem is not a problem exclusive to this very bright developer, it is a bad habit that we as an industry have picked up somewhere along the line and I'm here to say "Stop The Insanity!". Consider the following code: 1: if (_privateDataObject.Methodology != null) 2: { 3: if (_privateDataObject.Methodology == "00") 4: { 5: if (_privateDataObject.Amount != null) 6: { 7: if (IsNumeric(_privateDataObject.Amount)) 8: { 9: if (Convert.ToDecimal(_privateDataObject.Amount )==0 ) 10: { 11: bReturnValue =true; 12: } 13: else 14: { 15: 16: bReturnValue =false; 17: } 18: } 19: else 20: { 21: 22: bReturnValue =false; 23: } 24: } 25: else 26: { 27: 28: bReturnValue =false; 29: } 30: } 31: else 32: { 33: 34: bReturnValue =false; 35: } 36: } 37:  38: return bReturnValue; This decision weighs in at over 38 lines. Let's look at what the warning signs in this method should have been that it needed to be coded differently. The first and most important is that this follows a very basic pattern we see in code, we are seeking for single complex condition and want to return a "true" if we find it, and "false" in all other cases. This pattern is so basic it is taught in every Intro to Programming course ever. The pattern has a common name "Boolean AND" and is a part of every language (that I know of) on the planet. Refactored to accomidate for this pattern we end up with :   1: if (_privateDataObject.Methodology != null && 2: _privateDataObject.Methodology == "00" && 3: _privateDataObject.Amount != null && 4: IsNumeric(_privateDataObject.Amount) && 5: Convert.ToDecimal(_privateDataObject.Amount ) == 0) 6: { 7: bReturnValue =true; 8: } 9: else 10: { 11: bReturnValue =false; 12: } 13:  14: return bReturnValue;From 38 lines down to 14, not bad. And this version is not even as short (in line count) as it could be in favor of readability (spreading the expression across multiple lines) and to include braces (which are optional with only 1 command). Now that we've tamed the wild nested if, let's look at another problem. Why set a value, only to immediately return that value once you've decided on the result? Just return the value immediately. This small win nets us the following code: 1: if (_privateDataObject.Methodology != null && 2: _privateDataObject.Methodology == "00" && 3: _privateDataObject.Amount != null && 4: IsNumeric(_privateDataObject.Amount) && 5: Convert.ToDecimal(_privateDataObject.Amount ) == 0) 6: { 7: return true; 8: } 9: else 10: { 11: return false; 12: } From 14 to 12, not bad, and even less un-needed code. The final refactoring is based on the fact that this code is searching for a boolean value using boolean expressions. That means that to reach true "ruthless" refactoring we should end up with the following:  1: return _privateDataObject.Methodology != null && 2:_privateDataObject.Methodology == "00" && 3:_privateDataObject.Amount != null && 4:IsNumeric(_privateDataObject.Amount) && 5:Convert.ToDecimal(_privateDataObject.Amount ) == 0;Final result, 5 lines of code, same functionality. Important note to the Visual Basic developers out there, && is the equivalent of "AndAlso" in VB, not simply "And", hence why this code does not blow up with a NullReferenceException. I implore every developer reading this to get into the habit of considering how to refactor code as soon as you've got it working, and I mean on a method by method basis. Even if you're not using a "TDD" methodology, this is a very good habit to get into because every time we change code we've introduced the chance to improve either the readability or performance of the code as well. It is natural to reach "working" code and want to move on, but spending 10 minutes to examine how you got it working will pay off in the long run, I assure you.

Reflector 5.0 changes .NET Blogging

Last year I had the pleasure of meeting Scott Hanselman (who also talked about this subject today) when he was in town to speak at the Dallas .NET User Group and North Dallas .NET User Group. I told him "I'm paid more today because of you, thanks." and he quipped that perhaps he should setup a "Hanseltax". Well I don't know that I'm ready to start forking over cash to Scott just yet, he costs me enough in gadgets already, but I might just be convinced that a "RoederTax" is necessary after the release of Reflector 5.0.Lutz Roeder's Reflector is a must have for all .NET developers, period, full stop. If you don't have this on your box yet, stop reading this right now and go download it. The latest version includes the ability to set a display font size, which I much appreciate given the 1400x1050 resolution of my Toshiba M200 Tablet, and an incredible new Custom Protocol Handler registered to code://.Why is this so incredibly cool? Because now it becomes possible to link directly to methods from a blog post. For instance if I'm writing about XML, as I'm like to do from time to time, I might say you need to check out System.Xml.XmlReader and if you've got Reflector 5.0 installed it will open Reflector and open that exact method for you to examine.There are a ton of other features in Reflector 5.0, but I doubt that many will be affecting my life as quickly as this one. Lambda Expression, LINQ syntax, C# 3.0/.NET 3.5 support are all great, but code:// will be used today!

Temporary Post Used For Style Detection (fe6c10b8-f62b-4d82-b9d5-d30e3a1bba35)

This is a temporary post that was not deleted. Please delete this manually. (f1b48d33-090f-42a4-af2a-74e5e28b41ae)