Up to this point, we have mainly been calling or utilizing built-in helper methods available to us via the .NET framework. However, now you will learn how to define, and call, simple helper methods of your own making. To put it simply, a method is a named block of code that executes, in full, whenever you reference it elsewhere by calling it by name followed by the invocation parentheses. For example, string.Format(), int.Parse(), and random.Next() are just a few of the built-in methods we have already worked with thus far.
There's a few reasons for why you would ever create your own helper method. One reason is simply code reuse; wrapping up a common code block into a named method whenever you see it required in two or more places. This allows you to avoid unnecessary redundant code throughout your program. Another reason is to abstract away complicated code, breaking it up into methods that commit a certain process without requiring you to always to look at the details of that process.
There's an old saying that your code should “read like a story.” In other words, if you have a complex problem that is housed within a single method, it becomes monolithic and difficult to read. However, if you split it up into smaller code blocks - and give each of those code blocks a descriptive name of what that code block is attempting to do - then you can read it out, line-by-line, focusing on what is generally happening, rather than every banal detail of how it’s happening.
It’s often typical for programmers to first tackle a problem by writing all of the code in a single method, not worrying about breaking it up into individual methods right away. Breaking up monolithic code, after-the-fact, is a technique called “refactoring”. You’ll be seeing this in action shortly, but first, start this lesson by creating a new ASP.NET project called “CS-ASP_028” with the following Server Controls and Programmatic IDs:
This is going to be a simple application that converts between various measurement formats and displays the results in real-time. Notice that there is no button to PostBack to the server, and that’s because the RadioButtons and TextBoxes should have a property called “AutoPostBack.” Be sure to change this property for each of the Controls mentioned. This will effectively PostBack to the server when each element is changed:
The event that fires upon PostBack will be the CheckedChanged Action event for the CheckBoxes or the TextChanged for the TextBox:
Make sure to set each Server Control, except resultLabel, with an Action event named accordingly:
Also, each RadioButton should be set to the same GroupName in the Properties Window:
Now, what you could do is write out each event/method with minor differences depending on the measurement it’s dealing with. This will create a very obvious pattern, which should be a tip that a helper method might be useful to avoid so much duplicate code:
But before we refactor this, let’s briefly mention some unfamiliar code elements seen in each of these methods. Each method has some validation code to make sure acceptable inputs have been provided by the user. The first if() statement checks to see if quantityTextBox.Text is empty - after it’s been trimmed of whitespace - and exits the method if that is the case. The next if() statement simply checks to see if the value entered is non-numeric and also exits if that is the case.
There are extra elements in this line of code that you will become familiar with shortly. However, for the time being just know that the Double.TryParse() method returns true if it can successfully convert the input to a double, and it also returns the second argument – quantity – converted to a double via the out keyword. And finally, provided that the user-input values pass validation of the previous two if() statements, we perform the calculation and display it though the resultLabel. Now, to consolidate all of this duplicate code, let’s simply take the code common to each of these methods and put it all in its own custom helper method called calculateCups():
The code that’s different for each method is the part that performs particular calculations for each conversion. However, that can also be put into this helper method via a series of if() statements underneath the previous validation code:
Remember that with these if() statements that only perform one operation, there is no need to create a code block to hold the execution code. It would be perfectly fine to do so; but for readability's sake, it is left out in this example.
Now, you can erase all of the previous code in the methods/events, and instead just reference the helper method, by name, in each of those methods/events:
Whenever you reference a method by name followed by the invocation parentheses, it is said that you are calling the method. You are essentially “getting on the phone” and calling the method, asking it to then execute its code block each time you place a call to it.
When you run the application, it will work as it did before:
Be sure to include the invocation parentheses when calling a method that you want to execute, or else you will get an error:
Another common principle in coding is called the “DRY” principle. It stands for “don’t repeat yourself.” Repetition becomes a big problem in your code as the code-base grows larger and requires changes within it. You might imagine a scenario in which end-users are displeased upon you fixing a bug in one part of your application, while the bug persists in another part of your application where the repeated code (along with the repeated bug) may be missed.
Lesson 28 - Creating and Calling Simple Helper Methods