© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2022
G. ByrneTarget C#https://doi.org/10.1007/978-1-4842-8619-7_12

12. Methods

Gerard Byrne1  
(1)
Belfast, Ireland
 

Methods: Modularization

We learned in Chapter 11 that arrays are a very important programming structure when we need to “store” a collection of data, variables or objects, of the same data type. We saw that arrays in C# are of a fixed size. Once we declare the size of the array, it cannot be altered. Each item in an array can be referenced using its index, which is also called its subscript, and we can use the foreach loop to iterate the array items. With the foreach iteration, we do not need to use a counter as the foreach construct handles the indexing for us. If we wish to reference an index in an iteration, we can use the more traditional for, while, or do while iteration. We also learned that we could cause an IndexOutOfBounds exception if we are not careful in our coding.

Methods: Concepts of Methods and Functions

Most commercial programs will involve large amounts of code, and from a maintenance and testing perspective, it is essential that the program has a good structure. Well-written and organized programs allow those who maintain or test them to
  • Follow the code and the flow of events easier.

  • Find things quicker.

Just look at Figure 12-1 and think which image fits with the description of finding things easier.

Two photographs of the rack with clothes scattered and unorganized on the left and a rack with the clothes organized, respectively refer to the programming structure.

Figure 12-1

Organized or not?

Would we say the right-hand image? We might say that in the right-hand image, there is a sense of organization, there is space to see things, and there is a sense of calm. The left-hand image, we might say, gives a sense of confusion, clutter, and not caring. We do not want our code to look or feel like the left-hand image.

One way to help structure the program code is to break it into small functional parts with each part performing only one task. When we have a functional part, which does one specific thing, it may be possible for that functional part to be used by other parts of the program. These small functional parts can be thought of as subprograms or methods or functions, or sometimes they are called procedures . The words function and method are often used interchangeably. If we think about functions in mathematics, for example, we can have mathematical functions such as square root, sin, cos, and tan, as shown in Figure 12-2.

A screenshot distinguishes the method and function. On the left is a trigonometry option, while on the right is a function.

Figure 12-2

Method or function?

According to the Microsoft site

A method is a code block that contains a series of statements. A program causes the statements to be executed by calling the method and specifying any required method arguments.

In C#, every executed instruction is performed in the context of a method. The Main() method is the entry point for every C# application, and it is called by the Common Language Runtime (CLR) when the program is started.

Some Points Regarding Methods

  • A method begins with an access modifier. The access modifier will determine the visibility of the method from another class. If we set the access modifier as
    • public, the method is accessible inside the class it is created in and is available from outside this class

    • private, the method is only accessible inside the class it is created in

    • protected, the method is only accessible inside the class it is in or in a class that is derived from the class

    • internal, the method is only accessible inside the same assembly but not from another assembly

  • A method access modifier is followed by the method return type. The return type means the data type of the object that is being returned by the method. We can return any of the data types we have looked at, for example, int, float, double, char, string, or bool. Or we can return a type that we have defined. If the method will not return a value, then the return type is said to be void – the keyword void still needs to appear .

  • The return type is followed by the method name. The method name should follow good coding principles and let the reader know what the method is doing, simply by reading the name.

  • The method name is followed by open and close brackets ().

  • Inside the brackets () there may be a list of parameters. The parameters are variables that will hold any values passed to the method. The parameters will have a data type, which will be stated in front of the parameter name. The list of parameters is enclosed in parentheses (). Not every method will accept parameters; they are optional. So the method can contain no parameters – they can be referred to as parameterless methods.

  • The parentheses () are followed by opening and closing curly braces {}. Inside the curly braces is where the code, business logic, goes.

  • Methods are coded inside the class but outside the Main method, if there is a Main method in the class.

Figure 12-3 shows the general format of a method with a specific method also shown.

A screenshot distinguishes the general format and specific example of a method.

Figure 12-3

General format for a method, with a specific example

Examples

We will go into the structure more as we progress, but for now, we will look at three examples that fit the preceding rules:
  1. 1.
    public void CalculateCommission()
    • Here the access modifier is public.

    • The method will not return a value; it therefore returns void.

    • The method name is CalculateCommission.

    • The method has no parameters, so it takes in no values, no variables or objects.

     
  2. 2.
    private double CalculateCommission()
    • Here the access modifier is private.

    • The method will return a value, which is of data type double.

    • The method name is CalculateCommission.

    • The method has no parameters, so it takes in no variables or objects – it is parameterless.

     
  3. 3.
    private double CalculateCommission(double salesAmount, double commissionRate)
    • Here the access modifier is private.

    • The method will return a value, which is of data type double.

    • The method name is CalculateCommission.

    • The method accepts, takes in, two parameters. The first parameter is called salesAmount, which has a data type of double; and the second parameter is called commissionRate, which has a data type of double.

     
Some Other Important Points
  • A method can contain one or more statements.

  • A method name can use any valid identifier that we want.

  • A method name should not be a C# keyword.

  • The method name is used to call the method, and when we call the method, we are asking the method to execute its code and then return to the code that made the call.

  • There is a very important method called Main( ) and it is reserved for the method that begins execution of your program.

In Figure 12-4, MethodOne() is called from within the Main() method. The application code will look outside the Main() method for a method with the name MethodOne(). When it finds MethodOne(), it executes the lines of code within it and then returns to the code within the Main() method .

A diagram presents the main method divided into MethodOne and MethodTwo.

Figure 12-4

Main() method that calls two methods

After returning from MethodOne(), the next lines of code, indicated as some business logic in the code in Figure 12-4, are executed until the second method, MethodTwo(), is called. When MethodTwo() is called, the application code will again look outside the Main() method, but this time for a method with the name MethodTwo(). When it finds MethodTwo(), it executes the lines of code within it and then returns to the code within the Main() method.

Even looking at this simplified flow diagram, we get a sense that
  • Methods can be kept separate from the main code and called as required.

  • The methods are coded outside the Main() method.

  • Methods are small blocks of code, as we can see from the dotted areas in Figure 12-4.

Modern programming style dictates that a method should do one thing and one thing only. Methods that do more than one thing should be split into further methods. As a caveat we need to be mindful that creating every method to do one thing can actually make the code less readable and possibly harder to maintain, so we have to strike a balance and be realistic, and that is part of being a developer. Essentially, we have three types of methods, and we will look at these now to see how they are used, their similarities, and their differences.

Three Types of Methods

  • Void method

public void CalculateCommission();
Listing 12-1

Void method

  • The code in Listing 12-1 is what we looked at earlier, and we saw that this type of method executed code and did not return any value – it is a void method.

  • Value method

private double CalculateCommission();
Listing 12-2

Value method

  • The code in Listing 12-2 is what we looked at earlier, and we saw that this type of method executed code and then returned a value. The value it returns is a variable, and the variable must have a data type that matches the return type stated after the access modifier and before the method signature. In this example we are returning a value of type double – it is a value method.

  • Parameter method

private double CalculateCommission(double salesAmount, double commissionRate);
Listing 12-3

Parameter method

  • The code in Listing 12-3 is what we looked at earlier, and we saw that this type of method accepted one or more parameters. The parameters are just variables or objects, so they have a data type, and we give them a name of our choosing. The method executes code, which will probably use the variables passed in as parameters. Otherwise, why would we accept the parameters? The method can also return a value, in which case it is also a value method, or it may not return a value, in which case it is also a void method. This is a parameter method.

  • In Listing 12-2 the return type is a double, so the method is a value method, but it accepts, takes in, no value, so it is also a parameterless method.

  • In Listing 12-3 the return type is a double, so the method is a value method, and it accepts, takes in, two values of data type double, so it is also a parameter method.

  • In Listing 12-4 the return type is a void, so the method is a void method, and it accepts, takes in, one value of data type double, so it is also a parameter method .

private void CalculateCommission(double salesAmount);
Listing 12-4

Void/parameter method

Interestingly all the methods in Listings 12-1, 12-2, 12-3, and 12-4 have the same name, CalculateCommission, but they return different types or accept different parameters. We will talk about this later when we discuss method overloading.

Void Methods

When we call a method, the lines of code within the method are implemented. In Figure 12-4 we saw that when MethodOne() was called, the program looked for MethodOne(), the lines of code were executed, and control of the program was returned to the main program.

When a method does not return a value, it is said to be a void method. The declaration void indicates that the function returns no value to the caller. It is important to realize that every function declaration specifies a return type, even if it’s void.

An example of a void method is shown in Listing 12-5 .
  public void OdometerReading()
  {
      /// Ask the user to input the value on the odometer
      Console.WriteLine("What is the odometer reading");
      // Read the value entered by the user
      odometerReadingEntered = int.Parse(Console.ReadLine());
  }
Listing 12-5

Void method

Code Analysis
  • The method has an access modifier of public so the method will be available to all code inside the class or from outside the class.

  • The return type is void so the method will not return any value, and we will therefore not see the last line of code in the method saying return, but we should be aware that the return is still there and the compiler infers it. We can also have the return statement at any position in the method, but code following it will not be executed.

  • The name of the method is OdometerReading.

  • The open and close parentheses follow the name and are empty, which means that the method has no parameters, accepts no values.

  • The open and close curly braces follow the parentheses, and it is between these braces that the business logic, the code, goes.

  • The business logic code is very simple as it displays a message to the user through the Console.WriteLine() method.

  • It reads the user input from the console using the Parse() method.

  • The Parse() method accepts a parameter, which in this case is Console.ReadLine() - in other words, whatever is entered at the console.

  • The input is converted to an int, as we have used int.Parse() to convert.

The format for calling the method, using it, is by using the method name followed by the open and close parentheses as shown in Listing 12-6.
      OdometerReading();
Listing 12-6

Calling the void method

Add a new project to hold the code for this chapter.
  1. 1.

    Right-click the solution CoreCSharp.

     
  2. 2.

    Choose Add.

     
  3. 3.

    Choose New Project.

     
  4. 4.

    Choose Console App from the listed templates that appear.

     
  5. 5.

    Click the Next button.

     
  6. 6.

    Name the project Chapter12 and leave it in the same location.

     
  7. 7.

    Click the Next button.

     
  8. 8.

    Choose the framework to be used, which in our projects will be .NET 6.0 or higher.

     
  9. 9.

    Click the Create button.

     
Now we should see the Chapter12 project within the solution called CoreCSharp .
  1. 10.

    Right-click the project Chapter12 in the Solution Explorer panel.

     
  2. 11.

    Click the Set as Startup Project option.

     
Notice how the Chapter12 project name has been made to have bold text, indicating that it is the new startup project and that it is the Program.cs file within it that will be executed when we run the debugging.
  1. 12.

    Right-click the Program.cs file in the Solution Explorer window.

     
  2. 13.

    Choose Rename.

     
  3. 14.

    Change the name to MethodsVoid.cs.

     
  4. 15.

    Press the Enter key.

     
  5. 16.

    Double-click the MethodsVoid.cs file to open it in the editor window.

     
Now we can set up the code structure with a namespace, and inside it will be the MethodsVoid class, and inside the class will be the Main() method. The shortcut for creating the Main() method is to type svm and press the Tab key twice.
  1. 17.

    In the editor window, add the code in Listing 12-7.

     
namespace Chapter12
{
  internal class MethodsVoid
  {
    static void Main(string[] args)
    {
    } // End of Main() method
  } // End of MethodsVoid class
} // End of Chapter12 namespace
Listing 12-7

Class template when adding a class

We are now going to use the same code that we created for the Arrays.cs program, but we will make the code more maintainable by creating methods. Our methods for this example will be void methods.

Listing 12-8 is the code from the Arrays.cs program but with the original comments removed and a new comment added for each block of code that will become a method in our new program. This is an example to illustrate that methods can be used to modularize our code, but remember the caveat we mentioned earlier about striking a balance between all methods doing one thing and having readable and maintainable code.

Do not type the following code; it is for reference only and is the same as we coded in the last chapter. It is here merely to show which blocks of code will become methods.
static void Main(string[] args)
{
  /******************* METHOD ONE ******************/
  Console.WriteLine("How many claims are being made? ");
  numberOfClaimsBeingMade = Convert.ToInt32(Console.ReadLine());
  do
  {
    /*******************METHOD TWO ******************/
    Console.WriteLine("The current value of the " +
      "counter is :" + numberOfClaimsEntered + " ");
    /*******************METHOD THREE ******************/
    Console.WriteLine("What is your repair shop id? ");
    repairShopID = Console.ReadLine();
    /*******************METHOD FOUR ******************/
    repairShopClaims[arrayPositionCounter] = repairShopID;
    arrayPositionCounter++;
    /*******************METHOD FIVE ******************/
    Console.WriteLine("What is the vehicle policy number? ");
    vehiclePolicyNumber = Console.ReadLine();
    /*******************METHOD SIX ******************/
    repairShopClaims[arrayPositionCounter] = vehiclePolicyNumber;
    arrayPositionCounter++;
    /*******************METHOD SEVEN ******************/
    Console.WriteLine("What is the amount being claimed " +
      "for the repair? ");
    claimAmount = Convert.ToDouble(Console.ReadLine());
    /*******************METHOD EIGHT ******************/
    repairShopClaims[arrayPositionCounter] = claimAmount.ToString();
    arrayPositionCounter++;
    /*******************METHOD NINE ******************/
    Console.WriteLine("What was the date of the repair? ");
    claimDate = Convert.ToDateTime(Console.ReadLine());
    /*******************METHOD TEN ******************/
    repairShopClaims[arrayPositionCounter] =
                              claimDate.ToString();
    arrayPositionCounter++;
    /* Increment the loop counter by 1 */
    numberOfClaimsEntered++;
  } while (numberOfClaimsEntered < numberOfClaimsBeingMade);
  /*******************METHOD ELEVEN ******************/
  foreach (var itemInTheClaimsArray in repairShopClaims)
  {
    Console.WriteLine("The item in the array is:" +
      " " + itemInTheClaimsArray + " ");
  } // End of foreach iteration
} // End of Main() method
Listing 12-8

Program code

For this application
  • We will start by creating the variables to be used in the code. The variables will be created at the class level, inside the class and outside any methods. Later we will make local variables rather than class variables.

  • In creating the class-level variables, we will use the keyword static before each variable data type, because our Main() method is static, but when we study classes and objects in Chapter 13, we will have class-level variables that are not static, but that’s for a later discussion.

  • In terms of the word static , we will see more about it in Chapter 13, but for now just accept that static means belonging to this class.

  • Creating variables at the class level means that all the methods of the class will have access to them.

  • As we are on a chapter about creating and using methods, we will want to have easy access to the variables, but once we understand a bit more about methods, we will change the approach of using class-level variables and make use of local variables instead.

Note

We still have the code from the Arrays.cs class so we can copy and paste the code into this MethodsVoid.cs class , as we need it.
  1. 18.

    Amend the code, as in Listing 12-9, to declare and create the array at the class level, remembering to use the keyword static.

     
using System;
namespace Chapter12
{
  internal class MethodsVoid
  {
   /*
   The array is going to hold the data for 2 claims.
   Each claim has four pieces of information. The number of
   data items is therefore 2 multiplied by 4 = 8.
   So, we will make the array for this example of size 8.
   Not the best way to do things but fine for now.
   */
    static string[] repairShopClaims = new string[8];
    static void Main(string[] args)
    {
    } // End of Main() method
  } // End of MethodsVoid class
} // End of Chapter12 namespace
Listing 12-9

Declare and create the array

  1. 19.

    Amend the code, as in Listing 12-10, to create the variables at the class level. We must add the word static in front of the data type.

     
    static string[] repairShopClaims = new string[8];
    /*
    We will setup our variables that will be used in the
    quote application. The details will be:
    •   the repair shop unique id (string)
    •   the vehicle insurance policy number (string)
    •   the claim amount (double)
    •   the date of the claim (date)
    */
    static string repairShopId;
    static string vehiclePolicyNumber;
    static double claimAmount;
    static DateTime claimDate;
    static int numberOfClaimsBeingMade;
    static int numberOfClaimsEntered = 0;
    static int arrayPositionCounter = 0;
    static void Main(string[] args)
    {
    } // End of Main() method
Listing 12-10

Create the variables using the static keyword

Note

Methods are created outside the Main() method but inside the class. We can add the methods above the Main() method or below it. Here we will add the methods below the Main() method, so we need to be careful and make sure to add the methods below the Main() method but still inside the class, which is indicated by the second last curly brace }. The last curly brace } represents the end of the namespace.

We will now create the first method that will hold the code asking the user how many claims will be made and then collecting the user input from the console.
  1. 20.

    Amend the code, as in Listing 12-11, to create the first method, which will be called HowManyClaimsAreBeingMade().

     
  } // End of Main() method
  /*****************************************************
  All the methods will be located here.
  They are outside the main but inside the class
  *****************************************************/
  /******************* METHOD ONE ******************/
  public static void HowManyClaimsAreBeingMade()
  {
    /*
    Read the user input for the number of claims being made
    and convert the string value to an integer data type
    */
  Console.WriteLine("How many claims are being made? ");
  numberOfClaimsBeingMade = Convert.ToInt32(Console.ReadLine());
  } // End of HowManyClaimsAreBeingMade() method
} // End of MethodsVoid class
} // End of Chapter12 namespace
Listing 12-11

Create method 1 outside the Main() method

Remember to add the rest of the methods below the Main method and just above the class curly brace }.
  1. 21.

    Amend the code, as in Listing 12-12, to create the second method, which will be called CurrentValueOfCounter() .

     
    /******************* METHOD TWO ******************/
    public static void CurrentValueOfCounter()
    {
      Console.WriteLine("The current value of the counter " +
        "is :" +numberOfClaimsEntered + " ");
    } // End of CurrentValueOfCounter() method
  } // End of MethodsVoid class
} // End of Chapter12 namespace
Listing 12-12

Create method 2 outside the Main() method

  1. 22.

    Amend the code, as in Listing 12-13, to create the third method, which will be called ReadTheRepairShopId() .

     
    /******************* METHOD THREE ******************/
    public static void ReadTheRepairShopId()
    {
      Console.WriteLine("What is your repair shop id? ");
      repairShopId = Console.ReadLine();
    }// End of ReadTheRepairShopId() method
  } // End of MethodsVoid class
} // End of Chapter12 namespace
Listing 12-13

Create method 3 outside the Main() method

  1. 23.

    Amend the code, as in Listing 12-14, to create the fourth method, which will be called WriteRepairShopIdToTheArray() .

     
    /******************* METHOD FOUR ******************/
    public static void WriteRepairShopIdToTheArray()
    {
      repairShopClaims[arrayPositionCounter] = repairShopId;
      arrayPositionCounter++;
    } // End of WriteRepairShopIdToTheArray() method
  } // End of MethodsVoid class
} // End of Chapter12 namespace
Listing 12-14

Create method 4 outside the Main() method

  1. 24.

    Amend the code, as in Listing 12-15, to create the fifth method, which will be called ReadTheVehiclePolicyNumber() .

     
    /******************* METHOD FIVE ******************/
    public static void ReadTheVehiclePolicyNumber()
    {
      Console.WriteLine("What is the vehicle policy number? ");
      vehiclePolicyNumber = Console.ReadLine();
    } // End of ReadTheVehiclePolicyNumber() method
  } // End of MethodsVoid class
} // End of Chapter12 namespace
Listing 12-15

Create method 5 outside the Main() method

  1. 25.

    Amend the code, as in Listing 12-16, to create the sixth method, which will be called WriteVehiclePolicyNumberToTheArray() .

     
    /******************* METHOD SIX ******************/
    public static void WriteVehiclePolicyNumberToTheArray()
    {
      repairShopClaims[arrayPositionCounter]=vehiclePolicyNumber;
      arrayPositionCounter++;
    } // End of WriteVehiclePolicyNumberToTheArray() method
  } // End of MethodsVoid class
} // End of Chapter12 namespace
Listing 12-16

Create method 6 outside the Main() method

  1. 26.

    Amend the code, as in Listing 12-17, to create the seventh method, which will be called ReadTheAmountBeingClaimed() .

     
    /******************* METHOD SEVEN ******************/
    public static void ReadTheAmountBeingClaimed()
    {
      Console.WriteLine("What is the amount being " +
        "claimed for the repair? ");
      claimAmount = Convert.ToDouble(Console.ReadLine());
    } // End of ReadTheAmountBeingClaimed() method
  } // End of MethodsVoid class
} // End of Chapter12 namespace
Listing 12-17

Create method 7 outside the Main() method

  1. 27.

    Amend the code, as in Listing 12-18, to create the eighth method, which will be called WriteClaimAmountToTheArray() .

     
    /******************* METHOD EIGHT ******************/
    public static void WriteClaimAmountToTheArray()
    {
      repairShopClaims[arrayPositionCounter]
                  = claimAmount.ToString();
      arrayPositionCounter++;
    } // End of WriteClaimAmountToTheArray() method
  } // End of MethodsVoid class
} // End of Chapter12 namespace
Listing 12-18

Create method 8 outside the Main() method

  1. 28.

    Amend the code, as in Listing 12-19, to create the ninth method, which will be called ReadTheRepairDate() .

     
    /******************* METHOD NINE ******************/
    public static void ReadTheRepairDate()
    {
      Console.WriteLine("What was the date of the repair? ");
      claimDate = Convert.ToDateTime(Console.ReadLine());
    } // End of method ReadTheRepairDate() method
  } // End of MethodsVoid class
} // End of Chapter12 namespace
Listing 12-19

Create method 9 outside the Main() method

  1. 29.

    Amend the code, as in Listing 12-20, to create the tenth method, which will be called WriteRepairDateToTheArray() .

     
    /******************* METHOD TEN ******************/
    public static void WriteRepairDateToTheArray()
    {
      repairShopClaims[arrayPositionCounter]
                  = claimDate.ToString();
      arrayPositionCounter++;
    } // End of method WriteRepairDateToTheArray() method
  } // End of MethodsVoid class
} // End of Chapter12 namespace
Listing 12-20

Create method 10 outside the Main() method

  1. 30.

    Amend the code, as in Listing 12-21, to create the eleventh method, which will be called DisplayAllItemsInTheArray() .

     
    /******************* METHOD ELEVEN ******************/
    public static void DisplayAllItemsInTheArray()
    {
      foreach (var itemInTheClaimsArray in repairShopClaims)
      {
        Console.WriteLine("The item in the array " +
          "is: " + itemInTheClaimsArray + " ");
      }
    } // End of method DisplayAllItemsInTheArray() method
  } // End of MethodsVoid class
} // End of Chapter12 namespace
Listing 12-21

Create method 11 outside the Main() method

Now we have created the methods, each executing a small amount of code. We can call any method, at any time, from within the Main() method in the program class or indeed from any method. In the next chapter, we will see how we could call the methods from within a different class.

We will now

  • Call method 1 from within the Main() method.

  • Add a do while iteration in the Main() method.

  • Call methods 2–10 from within the do while iteration.

  • Call method 11 from outside the do while iteration but within the Main() method.

  1. 31.

    Amend the code, as in Listing 12-22.

     
  static void Main(string[] args)
  {
    // Call the method that asks how many claims will be entered
    HowManyClaimsAreBeingMade();
    do
    {
      // Call the methods as required
      CurrentValueOfCounter();
      ReadTheRepairShopId();
      WriteRepairShopIdToTheArray();
      ReadTheVehiclePolicyNumber();
      WriteVehiclePolicyNumberToTheArray();
      ReadTheAmountBeingClaimed();
      WriteClaimAmountToTheArray();
      ReadTheRepairDate();
      WriteRepairDateToTheArray();
      /* Increment the loop counter by 1 */
      numberOfClaimsEntered++;
    } while (numberOfClaimsEntered < numberOfClaimsBeingMade);
    } // End of Main() method
Listing 12-22

Create the method calls from within the Main() method

  1. 32.

    Amend the code, as in Listing 12-23, by adding, within the Main() method and outside the do while iteration, a call to the display method.

     
      /* Increment the loop counter by 1 */
      numberOfClaimsEntered++;
    } while (numberOfClaimsEntered < numberOfClaimsBeingMade);
      DisplayAllItemsInTheArray();
    } // End of Main() method
Listing 12-23

Call method 11 to display the data

  1. 33.

    Click the File menu.

     
  2. 34.

    Choose Save All.

     
  3. 35.

    Click the Debug menu.

     
  4. 36.

    Choose Start Without Debugging.

     
  5. 37.

    Click in the console window.

     
The console window will appear and ask the user how many claims are being made.
  1. 38.

    Type 2 and press the Enter key.

     
The console window will appear and ask the user to input the repair shop id.
  1. 39.

    Type RS000001 and press the Enter key.

     
The console will now ask the user to input the vehicle policy number.
  1. 40.

    Type VP000001 and press the Enter key.

     
The console will now ask the user to input the claim amount.
  1. 41.

    Type 1999.99 and press the Enter key.

     
The console will now ask the user to input the date of the repair.
  1. 42.

    Type 2021/10/01 and press the Enter key.

     
The console window will now ask the user to input the repair shop id.
  1. 43.

    Type RS000001 and press the Enter key.

     
The console will now ask the user to input the vehicle policy number.
  1. 44.

    Type VP001234 and press the Enter key.

     
The console will now ask the user to input the claim amount.
  1. 45.

    Type 2500.99 and press the Enter key.

     
The console will now ask the user to input the date of the repair.
  1. 46.

    Type 2021/10/01 and press the Enter key.

     
Iteration 2 is now completed; the block of code has been executed for the second time. The claims counter will now be incremented by 1 and become a 2. The comparison is made to see if the claims counter value is less than 2, and as it is not, the iterations will end. Figure 12-5 shows the output from the application.

A screenshot of the console window depicts the first iteration at the top and the second iteration at the bottom, respectively by void methods. The execution of the block of code is depicted.

Figure 12-5

Application output using void methods to modularize the code

The output shown in Figure 12-5 verifies that the array actually does hold the data entered by the user as we have iterated the array and displayed the eight values. Our array is a single-dimensional array holding items of data type string.
  1. 47.

    Press any key to close the console window.

     

So now we have refactored our original arrays code and created methods that have small amounts of code. The code is much neater as all we have in the Main() method are a series of calls to the methods. The methods sit outside the Main() method, but still inside the class. This is now a good example of modern programming where methods are an essential feature of maintainable code – it is modularization . With the code being decomposed into small methods, it is a relatively easy process to test these small code blocks. We could improve the code, but this is a great starting point for modularized code.

Value Methods

In the previous example when we called a method, the lines of code within the method were implemented and then control of the program was returned to the main program, to the calling statement. When a method is required to return a value to the calling statement, it is said to be a value method . When we return a value, we have learned from the start of our programming the applications in this book that all variables have a data type – for example, int, double, or string – and these data types are part of the C# programming language. In the last chapter we looked at arrays, and the arrays we created held objects that had a data type. So a value method could return a built-in data type such as int or double, or it could return our own data type such as an array that we have created. In looking at void methods , we used the return type void in front of the method signature as in Listing 12-24.
      public void GetScoreDetails();
Listing 12-24

Void method

But when we have a value method that returns a variable or object of a specific data type, we must state the data type in front of the method signature as in Listing 12-25.
      public int GetScoreDetails();
      public double GetScoreDetails();
      public string GetScoreDetails();
Listing 12-25

Value methods

Every method declaration specifies a return type, even if it’s void.
public int GetScoreDetails()
{
  // Ask the user to input the Score for Game One
  Console.WriteLine("What is the Score for Game One");
  // Read the Score for Game One
  scoreInGameOne = int.Parse(Console.ReadLine());
  return scoreInGameOne
}
Listing 12-26

Value method sample code

Listing 12-26 Code Analysis
  • The method has an access modifier of public so the method will be available to all code inside the class or from outside the class.

  • The return type is int so the method will return a variable that must be of data type int, and the last line of code in the method, usually, says return followed by the variable or object name, but remember we read earlier that we can return from anywhere in the method.

  • The name of the method is GetScoreDetails.

  • The open and close parentheses () follow the name and are empty, indicating that the method accepts no parameters.

  • The open and close curly braces follow the parentheses and it is between these braces that the business logic goes.

  • The code uses the Console.WriteLine() method to display a message for the user.

  • The user input is then read from the console using the int.Parse() method.

  • The Parse() method accepts a parameter, which in this case is Console.ReadLine() – in other words, whatever is entered at the console.

  • The input is converted to an int as we have used int.Parse() to convert.

  • In the final line of code, the variable is returned, and it is of data type int.

The format for calling the method is by using the method name followed by the open and close parentheses, GetScoreDetails();.

Before we start coding an example of a value method, let us pause to think about the difference between a void method and value method as shown in Table 12-1.
Table 12-1

Difference between void and value methods

 

Void method

Value method

Signature

Will contain the keyword void

Will contain the keyword belonging to the data type being returned

Code

Will not contain a return keyword in the code

Will contain a return keyword in the code

Create and Use Value Methods
  1. 1.

    Right-click the class called MethodsVoid.cs within the Chapter12 project in the Solution Explorer panel.

     
  2. 2.

    Choose Copy.

     
  3. 3.

    Right-click the Chapter12 project in the Solution Explorer panel.

     
  4. 4.

    Choose Paste.

     
  5. 5.

    Right-click the MethodsVoid Copy.cs file, which is the copied file.

     
  6. 6.

    Choose Rename.

     
  7. 7.

    Name the class MethodsValue.cs.

     
  8. 8.

    Ensure that the MethodsValue.cs file is open in the editor window.

     
  9. 9.

    Rename the class in the open editor window from MethodsVoid to MethodsValue.

     
  10. 10.

    Right-click the Chapter12 project in the Solution Explorer panel.

     
  11. 11.

    Choose Properties from the pop-up menu.

     
  12. 12.

    Choose the MethodsValue.cs class in the Startup object drop-down list.

     
  13. 13.

    Close the Properties window.

     
We will now amend the code using some ordered steps :
  • In the required methods, change the keyword void to the data type that is to be returned.

  • In the required methods, add a return statement followed by the variable name being returned as the last line of the method.

We should be aware that if a method returns a value to a calling statement , then the returned value should be used for something. In other words, what use would the line of code in Listing 12-27 be if we called the method and it returned a value of 2?
    HowManyClaimsAreBeingMade();
Listing 12-27

Value method called and returned value not assigned to a variable

The answer to our question is no use at all. We need to assign the returned value to a variable or use it in some other way, and we will do this from within the Main() method where the call is made.

Now we will change the void methods to value methods by adding the return type on the first line and then returning the value as the last line of the method.
  1. 14.

    Amend method 1, HowManyClaimsAreBeingMade(), as in Listing 12-28.

     
  /******************* METHOD ONE ******************/
  public static int HowManyClaimsAreBeingMade()
  {
   /*
   Read the user input for the number of claims being made
   and convert the string value to an integer data type
   */
   Console.WriteLine("How many claims are being made? ");
   numberOfClaimsBeingMade = Convert.ToInt32(Console.ReadLine());
   return numberOfClaimsBeingMade;
  } // End of HowManyClaimsAreBeingMade() method
Listing 12-28

Method 1 return type changed and a return statement added

  1. 15.

    Amend the calling statement in the Main() method to assign the returned value to a variable as in Listing 12-29.

     
  static void Main(string[] args)
  {
    // Call the method that asks how many claims will be entered
    numberOfClaimsBeingMade = HowManyClaimsAreBeingMade();
    do
Listing 12-29

Call the method and assign the returned value to a variable

Looking at this line, we will see there is room for improvement in the code:

  • The variable numberOfClaimsBeingMade is the class-level variable and we are assigning it the value returned from the method HowManyClaimsAreBeingMade().

  • The HowManyClaimsAreBeingMade() method uses the same numberOfClaimsBeingMade class-level variable and has assigned it the value entered by the user.

  • Therefore, we could make the method code better by simply returning the value read in from the console as entered by the user rather than assigning it to the variable. This simple change helps illustrate good coding. We should also understand that variables should be declared, scoped, only where they are required, that is, local scope rather than “global.”

  1. 16.

    Amend the method 1 code to comment the assignment statement and return the converted input as in Listing 12-30.

     
  /******************* METHOD ONE ******************/
  public static int HowManyClaimsAreBeingMade()
  {
  /*
  Read the user input for the number of claims being made
  and convert the string value to an integer data type
  */
  Console.WriteLine("How many claims are being made? ");
  //numberOfClaimsBeingMade =Convert.ToInt32(Console.ReadLine());
  return Convert.ToInt32(Console.ReadLine());
  } // End of HowManyClaimsAreBeingMade() method
Listing 12-30

Comment the assignment and amend the return statement

The original line of code has been commented out, but it could be completely removed as shown in Listing 12-31. Remember YAGNI You Ain’t Going to Need It. It’s all part of the clean code ethos.
  1. 17.

    Remove the commented line so the method has the code as in Listing 12-31.

     
  /******************* METHOD ONE ******************/
  public static int HowManyClaimsAreBeingMade()
  {
  /*
  Read the user input for the number of claims being made
  and convert the string value to an integer data type
  */
  Console.WriteLine("How many claims are being made? ");
  return Convert.ToInt32(Console.ReadLine());
  } // End of HowManyClaimsAreBeingMade() method
Listing 12-31

Commented assignment removed

Amending the method to return the input is a good example of refactoring our code with the aim of making the code better. We will now follow the same process for some of the other methods, making them value methods and removing the line of code that is not required.
  1. 18.

    Amend method 3, ReadTheRepairShopId(), as in Listing 12-32.

     
    /******************* METHOD THREE ******************/
    public static string ReadTheRepairShopId()
    {
      Console.WriteLine("What is your repair shop id? ");
      return Console.ReadLine();
    }// End of ReadTheRepairShopId() method
Listing 12-32

Method 3 return type changed and a return statement added

  1. 19.

    Amend the calling statement in the Main() method to assign the returned value to a variable as in Listing 12-33.

     
    do
    {
    // Call the methods as required
    CurrentValueOfCounter();
    repairShopId = ReadTheRepairShopId();
    WriteRepairShopIdToTheArray();
Listing 12-33

Call the method and assign the returned value to a variable

  1. 20.

    Amend method 5, ReadTheVehiclePolicyNumber(), as in Listing 12-34.

     
    /******************* METHOD FIVE ******************/
    public static string ReadTheVehiclePolicyNumber()
    {
      Console.WriteLine("What is the vehicle policy number? ");
      return Console.ReadLine();
    } // End of ReadTheVehiclePolicyNumber() method
Listing 12-34

Method 5 return type changed and a return statement added

  1. 21.

    Amend the calling statement in the Main() method to assign the returned value to a variable as in Listing 12-35.

     
    do
    {
    // Call the methods as required
    CurrentValueOfCounter();
    repairShopID = ReadTheRepairShopId();
    WriteRepairShopIdToTheArray();
    vehiclePolicyNumber = ReadTheVehiclePolicyNumber();
    WriteVehiclePolicyNumberToTheArray();
Listing 12-35

Call the method and assign the returned value to a variable

  1. 22.

    Amend method 7, ReadTheAmountBeingClaimed (), as in Listing 12-36.

     
    /******************* METHOD SEVEN ******************/
    public static double ReadTheAmountBeingClaimed()
    {
      Console.WriteLine("What is the amount being " +
        "claimed for the repair? ");
      return Convert.ToDouble(Console.ReadLine());
    } // End of ReadTheAmountBeingClaimed() method
Listing 12-36

Method 7 amended to return a value

  1. 23.

    Amend the calling statement in the Main() method to assign the returned value to a variable as in Listing 12-37.

     
    do
    {
    // Call the methods as required
    CurrentValueOfCounter();
    repairShopID = ReadTheRepairShopId();
    WriteRepairShopIdToTheArray();
    vehiclePolicyNumber = ReadTheVehiclePolicyNumber();
    WriteVehiclePolicyNumberToTheArray();
    claimAmount = ReadTheAmountBeingClaimed();
    WriteClaimAmountToTheArray();
Listing 12-37

Call the method and assign the returned value to a variable

  1. 24.

    Amend method 9, ReadTheRepairDate(), to return the user input value as shown in Listing 12-38.

     
/******************* METHOD NINE ******************/
 public static DateTime ReadTheRepairDate()
 {
   Console.WriteLine("What was the date of the repair? ");
   return Convert.ToDateTime(Console.ReadLine());
 }// End of method ReadTheRepairDate()
Listing 12-38

Method 9 return type changed and a return statement added

  1. 25.

    Amend the calling statement in the Main() method to assign the returned value to a variable as in Listing 12-39.

     
    claimAmount = ReadTheAmountBeingClaimed();
    WriteClaimAmountToTheArray();
    claimDate = ReadTheRepairDate();
    WriteRepairDateToTheArray();
    /* Increment the loop counter by 1 */
    numberOfClaimsEntered++;
    } while (numberOfClaimsEntered < numberOfClaimsBeingMade);
Listing 12-39

Call the method and assign the returned value to a variable

  1. 26.

    Click the File menu.

     
  2. 27.

    Choose Save All.

     
  3. 28.

    Click the Debug menu.

     
  4. 29.

    Choose Start Without Debugging.

     
  5. 30.

    Click in the console window.

     
The console window will appear and ask the user how many claims are being made.
  1. 31.

    Type 2 and press the Enter key.

     
The console window will appear and ask the user to input the repair shop id.
  1. 32.

    Type RS000001 and press the Enter key.

     
The console will now ask the user to input the vehicle policy number.
  1. 33.

    Type VP000001 and press the Enter key.

     
The console will now ask the user to input the claim amount.
  1. 34.

    Type 1999.99 and press the Enter key.

     
The console will now ask the user to input the date of the repair.
  1. 35.

    Type 2021/10/01 and press the Enter key.

     
The console window will now ask the user to input the repair shop id.
  1. 36.

    Type RS000001 and press the Enter key.

     
The console will now ask the user to input the vehicle policy number .
  1. 37.

    Type VP001234 and press the Enter key.

     
The console will now ask the user to input the claim amount.
  1. 38.

    Type 2500.99 and press the Enter key.

     
The console will now ask the user to input the date of the repair.
  1. 39.

    Type 2021/10/01 and press the Enter key.

     
The number of claims entered is 2, and this is all that the user requested, so the do while loop is complete, and the next lines of code are the foreach iteration. As a result of the foreach iteration, the console will display all the items in the array as shown in Figure 12-6.

A screenshot of the console window depicts the first iteration at the top and the second iteration at the bottom, respectively by value methods. The execution of the block of code is depicted.

Figure 12-6

Application output using value methods to modularize the code

  1. 40.

    Press any key to close the console window.

     

So now we have changed some of the methods to make them value methods. A value method means a value, which has a data type, is returned from the method. When creating a value method and we talk about a method signature, the method signature does not contain the data type being returned, but the data type being returned appears before the method name.

This is great. We now have void and value methods within our code, and we will continue with the last main method type, the parameter method, which will also be a void or a value method.

Parameter Methods

It is possible to have our methods accept a value or multiple values and then use these values within the body of the method as part of the business logic processing. We could have a method that accepts two integer values and uses them in a multiplication or a method that accepts a string value and a quote amount and displays the two values. In using a parameter method , we pass it actual values , as arguments, when we call the method. When we are creating the parameter method, the parameters, and their data type, are enclosed as part of the method signature. When the arguments, actual values, are passed to the method, the method accepts these arguments, and their values are assigned to the parameters in the accepting method.

Note
  • A parameter is a variable or object in a method declaration and should be thought of as a placeholder that will hold the actual value when it is passed to the method from the calling statement.

  • An argument is the actual value passed to the method, which accepts it.

  • Think of the a of arguments as actual values.

  • We say that the method defines the parameters and accepts the arguments.

In using parameter methods, the calling method needs only to know what data type needs to be passed; it does not need to know what the method does with these values in its business logic. Figure 12-7 depicts the black box idea for a method that accepts values and outputs a result.

A flowchart presents the process in the parameter method. Initially, data values are passed, accept the arguments, and return the value.

Figure 12-7

Method is passed values and uses these in its business logic

By providing the method with the required input data, the method produces the required answer, the value to be returned. To obtain the correct answer, we must ensure that the correct input arguments are provided:
  • The right number of input arguments

  • The correct type of arguments

  • The correct order of the arguments

Example

By setting up the input data as the
  • Number of items

  • Cost per item

the result of a multiplication can be produced. The method will use the input data, perform its business logic and calculations, and produce a result.

The values passed into the method are known as arguments . The method is said to take them as its parameters, as shown in Figure 12-8.

A flowchart depicts how the method accepts the arguments as its parameters.

Figure 12-8

Method accepting arguments as its parameters

An example of a value method is shown in Listing 12-40.
public double AccumulateClaimAmount(double totalOfAllClaims, double claimAmount)
{
  double newTotal = totalOfAllClaims + claimAmount;
  return newTotal;
}
Listing 12-40

Parameter method that accepts one parameter

Listing 12-40 Code Analysis
  • The method has an access modifier of public so the method will be available to all code inside the class or from outside the class.

  • The return type is double so the method will return a variable that must be of data type double, and therefore the last line of code in the method will contain the keyword return followed by the variable name.

  • The name of the method is AccumulateClaimAmount.

  • The open and close parentheses () follow the name and hold two arguments passed to the method, and they are called totalOfAllClaims and claimAmount, which are of data type double.

  • The open and close curly braces follow the parentheses, and it is between these braces that the business logic is coded.

  • The business logic adds the variable values that have been passed in and assigns the value to a new local variable called newTotal.

  • In the final line of code, the newTotal variable is returned to the calling statement and it is of data type double.

The format for calling the parameter method is by using the method name followed by the open and close parentheses, and inside the parentheses are the arguments, the values. In our example there is only one value accepted by the parameter method so we will be passing one argument, as in Listing 12-41.
AccumulateClaimAmount(1000);
Listing 12-41

Calling the parameter method and passing it a value

Now before we start coding an example of a parameter method, pause, and think about how a parameter method is associated with a void method and a value method. Table 12-2 shows the association.
Table 12-2

Parameter method association with void and value methods

 

Parameter method

Signature

May contain the keyword void

May contain the keyword belonging to the data type being returned

Code

May not contain a return keyword on the last line of code

May contain a return keyword on the last line of code

Arguments

Will contain one or more arguments

Before we start adding new parameter methods to complete our code, let us think back to what we said earlier:

As we are on a chapter about creating and using methods, we will want to have easy access to the variables, but once we understand a bit more about methods, we will change the approach of using class-level variables and make use of local variables instead.

So now we have come to the stage where we can tidy our code and make more use of local variables and discard the class-level variables. The general steps we will use to create local variables when we can will be as follows:
  • In the do while construct where we call the method, we are assigning the value returned from the value method to a class-level variable, so we will move the class-level variable to within the do while so it is local.

  • Change the newly moved variable from having static in front of it, as the do while and therefore this variable are inside a static Main() method.

  • Next, we will pass the variable to the value method used to write the value to the array; we pass the value as an argument when we call the method.

  • We then need to make the value method used to write to the array into a parameter method so it can accept the argument being passed to it.

  • We then will use the parameter of the parameter method in writing to the array rather than using the class-level variable.

We will start with fixing the call to the ReadTheRepairShopId() method , and the other fixes will follow the same process.
  1. 1.

    Highlight the line of code declaring the class-level variable repairShopId, as in Listing 12-42.

     
    static string repairShopId;
    static string vehiclePolicyNumber;
    static double claimAmount;
    static DateTime claimDate;
Listing 12-42

Highlight the static variable – repairShopId

  1. 2.

    Right-click and choose Cut.

     
  2. 3.

    Paste the copied code into the line within the do while construct so we are assigning this copied variable to the value returned from the method ReadTheRepairShopId() , as shown in Listing 12-43.

     
      do
      {
        // Call the methods as required
        CurrentValueOfCounter();
        static string repairShopId = ReadTheRepairShopId();
        WriteRepairShopIdToTheArray();
Listing 12-43

Static variable is assigned the returned value from the method

Notice that the keyword static is underlined as an error, and if we hover over the red underline or look in the Error List window, we will see that it tells us that “The modifier ‘static’ is not valid for this.” We need to remove the keyword static as we are inside the static Main() method.
  1. 4.

    Remove the keyword static as in Listing 12-44.

     
      do
      {
        // Call the methods as required
        CurrentValueOfCounter();
        string repairShopId = ReadTheRepairShopId();
        WriteRepairShopIdToTheArray();
Listing 12-44

Static has been removed from the variable

  1. 5.

    Within the do while construct, call the WriteRepairShopIdToTheArray() method but pass the variable repairShopId as an argument, as in Listing 12-45.

     
      do
      {
        // Call the methods as required
        CurrentValueOfCounter();
        string repairShopId = ReadTheRepairShopId();
        WriteRepairShopIdToTheArray(repairShopId);
Listing 12-45

Pass the value as an argument to the method

Notice that the WriteRepairShopIdToTheArray() method name is underlined as an error, and if we hover over the red underline or look in the Error List window, we will see that it tells us that “No overload for method ‘ReadTheRepairShopId’ takes 1 arguments.” So the WriteRepairShopIdToTheArray() method, method 4, currently does not accept any values. It is not a parameter method; it is just a void method. We need to make the method into a parameter method that accepts one string value.
  1. 6.

    Amend method 4 so that is accepts a string parameter, which we will call repairShopId. Method 4 is now as in Listing 12-46.

     
    /******************* METHOD FOUR ******************/
    public static void WriteRepairShopIdToTheArray(string repairShopId)
    {
      repairShopClaims[arrayPositionCounter] = repairShopId;
      arrayPositionCounter++;
    } // End of WriteRepairShopIdToTheArray() method
Listing 12-46

Make the method a parameter method

With these steps completed, we have now removed a class-level variable and used a local variable instead, and we have created a parameter method, which is called and passed the value of the local variable. We will now repeat this process for the policy number, claim amount, and claim date.
  1. 7.

    Highlight the line of code declaring the class-level variable vehiclePolicyNumber, as in Listing 12-47.

     
    static string vehiclePolicyNumber;
    static double claimAmount;
    static DateTime claimDate;
Listing 12-47

Highlight the static variable – vehiclePolicyNumber

  1. 8.

    Right-click and choose Cut.

     
  2. 9.

    Paste the copied code into the line within the do while construct so we are assigning this copied variable to the value returned from the method ReadTheVehiclePolicyNumber() and remove the static, as shown in Listing 12-48.

     
     do
     {
       // Call the methods as required
       CurrentValueOfCounter();
       string repairShopId = ReadTheRepairShopId();
       WriteRepairShopIdToTheArray(repairShopId);
       string vehiclePolicyNumber = ReadTheVehiclePolicyNumber();
       WriteVehiclePolicyNumberToTheArray();
Listing 12-48

Static variable is assigned the returned value from the method

  1. 10.

    Within the do while construct, call the WriteVehiclePolicyNumberToTheArray() method but pass the variable vehiclePolicyNumber as an argument, as in Listing 12-49.

     
     do
     {
       // Call the methods as required
       CurrentValueOfCounter();
       string repairShopId = ReadTheRepairShopId();
       WriteRepairShopIdToTheArray(repairShopId);
       string vehiclePolicyNumber = ReadTheVehiclePolicyNumber();
       WriteVehiclePolicyNumberToTheArray(vehiclePolicyNumber);
Listing 12-49

Pass the value as an argument to the method

  1. 11.

    Amend method 6 so that is accepts a string parameter, which we will call vehiclePolicyNumber . Method 6 is now as in Listing 12-50.

     
    /******************* METHOD SIX ******************/
    public static void WriteVehiclePolicyNumberToTheArray(string vehiclePolicyNumber)
    {
      repairShopClaims[arrayPositionCounter] = vehiclePolicyNumber;
      arrayPositionCounter++;
    } // End of WriteVehiclePolicyNumberToTheArray() method
Listing 12-50

Make the method a parameter method

We will now repeat this process for the claim amount.
  1. 12.

    Highlight the line of code declaring the class-level variable claimAmount, as in Listing 12-51.

     
    static double claimAmount;
    static DateTime claimDate;
Listing 12-51

Highlight the static variable – claimAmount

  1. 13.

    Right-click and choose Cut.

     
  2. 14.

    Paste the copied code into the line within the do while construct so we are assigning this copied variable to the value returned from the method ReadTheAmountBeingClaimed() and remove the static, as shown in Listing 12-52.

     
    do
    {
      // Call the methods as required
      CurrentValueOfCounter();
      string repairShopId = ReadTheRepairShopId();
      WriteRepairShopIdToTheArray(repairShopId);
      string vehiclePolicyNumber = ReadTheVehiclePolicyNumber();
      WriteVehiclePolicyNumberToTheArray(vehiclePolicyNumber);
      double claimAmount = ReadTheAmountBeingClaimed();
      WriteClaimAmountToTheArray();
Listing 12-52

Static variable is assigned the returned value from the method

  1. 15.

    Within the do while construct, call the WriteClaimAmountToTheArray() method but pass the variable claimAmount as an argument, as in Listing 12-53.

     
    do
    {
      // Call the methods as required
      CurrentValueOfCounter();
      string repairShopId = ReadTheRepairShopId();
      WriteRepairShopIdToTheArray(repairShopId);
      string vehiclePolicyNumber = ReadTheVehiclePolicyNumber();
      WriteVehiclePolicyNumberToTheArray(vehiclePolicyNumber);
      double claimAmount = ReadTheAmountBeingClaimed();
      WriteClaimAmountToTheArray(claimAmount);
Listing 12-53

Pass the value as an argument to the method

  1. 16.

    Amend method 8 so that is accepts a parameter of type double, which we will call claimAmount. Method 8 is now as in Listing 12-54.

     
    /******************* METHOD EIGHT ******************/
    public static void WriteClaimAmountToTheArray(double claimAmount)
    {
      repairShopClaims[arrayPositionCounter]
                  = claimAmount.ToString();
      arrayPositionCounter++;
    } // End of WriteClaimAmountToTheArray() method
Listing 12-54

Make the method a parameter method

We will now repeat this process for the claim date.
  1. 17.

    Highlight the line of code declaring the class-level variable claimDate as in Listing 12-55.

     
    static DateTime claimDate;
Listing 12-55

Highlight the static variable – claimDate

  1. 18.

    Right-click and choose Cut.

     
  2. 19.

    Paste the copied code into the line within the do while construct so we are assigning this copied variable to the value returned from the method ReadTheRepairDate() and remove the static, as shown in Listing 12-56.

     
    do
    {
      // Call the methods as required
      CurrentValueOfCounter();
      string repairShopId = ReadTheRepairShopId();
      WriteRepairShopIdToTheArray(repairShopId);
      string vehiclePolicyNumber = ReadTheVehiclePolicyNumber();
      WriteVehiclePolicyNumberToTheArray(vehiclePolicyNumber);
      double claimAmount = ReadTheAmountBeingClaimed();
      WriteClaimAmountToTheArray(claimAmount);
      DateTime claimDate = ReadTheRepairDate();
      WriteRepairDateToTheArray();
Listing 12-56

Static variable is assigned the returned value from the method

  1. 20.

    Within the do while construct, call the WriteRepairDateToTheArray() method but pass the variable claimDate as an argument, as in Listing 12-57.

     
    do
    {
      // Call the methods as required
      CurrentValueOfCounter();
      string repairShopId = ReadTheRepairShopId();
      WriteRepairShopIdToTheArray(repairShopId);
      string vehiclePolicyNumber = ReadTheVehiclePolicyNumber();
      WriteVehiclePolicyNumberToTheArray(vehiclePolicyNumber);
      double claimAmount = ReadTheAmountBeingClaimed();
      WriteClaimAmountToTheArray(claimAmount);
      DateTime claimDate = ReadTheRepairDate();
      WriteRepairDateToTheArray(claimDate);
Listing 12-57

Pass the value as an argument to the method

  1. 21.

    Amend method 10 so that it accepts a parameter of type double, which we will call claimDate. Method 10 is now as in Listing 12-58.

     
    /******************* METHOD TEN ******************/
    public static void WriteRepairDateToTheArray(DateTime claimDate)
    {
      repairShopClaims[arrayPositionCounter]
                  = claimDate.ToString();
      arrayPositionCounter++;
    } // End of method WriteRepairDateToTheArray() method
Listing 12-58

Make the method a parameter method

These changes have made a real difference to our code because we have reduced the number of class-level variables, made good use of local variables, and used parameter methods. Yes, we could go further and get rid of the other three class-level variables, but for now this is excellent progress, and we can progress with some more parameter methods.

We will now add some parameter methods to the existing code where
  • The parameter method will accept two arguments, both of type double.

  • The values passed in will be the values of the claim being made and the existing total of all claims.

  • The method will use the values passed into it to find the new total of all the claims being made.

  • We will create a method that accepts the accumulated total of the claims and works out how much of the accumulated total is value-added tax (VAT).

  • The VAT amount will be included in the accumulated total, and the formula for the calculation is shown in Listing 12-59.

      vatamount = accumulated total passed in / 1.20;
Listing 12-59

Formula for calculating value-added tax

We will add a parameter method called AccumulateClaimAmount(), which has two parameters, one called claimAmountPassedIn and the other called totalOfAllClaims of data type double.
  1. 22.

    Add method 12, a new parameter method, as in Listing 12-60.

     
    /******************* METHOD TWELVE ******************/
    public static double AccumulateClaimAmount(double
    claimAmountPassedIn, double totalOfAllClaims)
    {
      totalOfAllClaims += claimAmountPassedIn;
      return totalOfAllClaims ;
    }// End of method AccumulateClaimAmount()
  } // End of MethodsValue class
} // End of Chapter12 namespace
Listing 12-60

Add a new parameter method

The method accumulates the total of all repair claims being entered by the user, so we also need to create the variable to hold this total. Here we have named the variable totalOfAllClaims , and we will declare this as a method-level variable assigning it an initial value of 0.00, as shown in Listing 12-61.
   static void Main(string[] args)
   {
    // Call the method that asks how many claims will be entered
     numberOfClaimsBeingMade = HowManyClaimsAreBeingMade();
     double totalOfAllClaims = 0.00;
     do
     {
Listing 12-61

Add the new method-level variable

Now we need to call the AccumulateClaimAmount() method , which we have just created, and pass it the claim amount, which has been entered, and the current total of all claims. This method just adds the value to the existing total value of all claims.
  1. 23.

    Amend the code to call the method, passing the claim amount and the current claims total as the arguments, as in Listing 12-62.

     
do
 {
 // Call the methods as required
 CurrentValueOfCounter();
 string repairShopId = ReadTheRepairShopId();
 WriteRepairShopIdToTheArray(repairShopId);
 string vehiclePolicyNumber = ReadTheVehiclePolicyNumber();
   WriteVehiclePolicyNumberToTheArray(vehiclePolicyNumber);
   double claimAmount = ReadTheAmountBeingClaimed();
   WriteClaimAmountToTheArray(claimAmount);
   totalOfAllClaims = AccumulateClaimAmount(claimAmount, totalOfAllClaims);
   DateTime claimDate = ReadTheRepairDate();
   WriteRepairDateToTheArray(claimDate);
   /* Increment the loop counter by 1 */
   numberOfClaimsEntered++;
  } while (numberOfClaimsEntered < numberOfClaimsBeingMade);
Listing 12-62

Call the parameter method from within the do while construct

Now we need to create

  • A value method that accepts the total of all claims as a parameter and then determines the VAT based on this value

  • A method-level variable to hold the VAT value

  • A void method that accepts the total of all claims and the VAT amount and displays a confirmation invoice showing the
    • Total of the claims without VAT

    • Total amount of VAT

    • Total of the claims including VAT

  1. 24.

    Amend the code, as in Listing 12-63, to include the method-level variable.

     
    static void Main(string[] args)
    {
     // Call the method that asks how many claims will be entered
      numberOfClaimsBeingMade = HowManyClaimsAreBeingMade();
      double totalOfAllClaims = 0.00;
      double vatAmount =0.00;
      do
      {
Listing 12-63

Add an additional local variable to hold the VAT amount

  1. 25.

    Amend the code to add the value and parameter method, method 13, as in Listing 12-64.

     
    /******************* METHOD THIRTEEN ******************/
    public static double DetermineVATAmount(double totalValueOfClaimsPassedIn, double vatAmount)
    {
      vatAmount = totalValueOfClaimsPassedIn -
                         (totalValueOfClaimsPassedIn / 1.20);
      return vatAmount;
    } // End of method DetermineVATAmount()
  } // End of MethodsValue class
} // End of Chapter12 namespace
Listing 12-64

Add additional method to determine the VAT amount

  1. 26.

    Amend the code in the Main() method to call the newly created VAT method, passing it the total value of the claims and the VAT amount, as in Listing 12-65.

     
   } while (numberOfClaimsEntered < numberOfClaimsBeingMade);
   vatAmount = DetermineVATAmount(totalOfAllClaims, vatAmount);
   DisplayAllItemsInTheArray();
 } // End of Main() method
Listing 12-65

Call the new method passing it the two arguments

  1. 27.

    Amend the code in the Main() method , as in Listing 12-66, to display the total of all claims.

     
  } while (numberOfClaimsEntered < numberOfClaimsBeingMade);
  vatAmount = DetermineVATAmount(totalOfAllClaims, vatAmount);
  DisplayAllItemsInTheArray();
  Console.WriteLine("The total amount claimed is: " + totalOfAllClaims);
    } // End of Main() method
Listing 12-66

Display the total of all claims

Now we can create the void method that accepts the total of all claims and the VAT amount and displays the invoice receipt.
  1. 28.

    Amend the code to add the new void method, method 14, which accepts the two arguments – it’s a parameter method, as in Listing 12-67.

     
    /******************* METHOD FOURTEEN ******************/
    public static void DisplayInvoiceReceipt(double
           totalValueOfClaimsPassedIn, double vatPassedIn)
    {
      Console.WriteLine(" Invoice for vehicle repairs ");
      Console.WriteLine("Nett claim " + (totalValueOfClaimsPassedIn - vatPassedIn) + " ");
      Console.WriteLine("VAT amount " + vatPassedIn + " ");
      Console.WriteLine("Total amount " + totalValueOfClaimsPassedIn + " ");
    } // End of method DisplayInvoiceReceipt()
  } // End of MethodsValue class
} // End of Chapter12 namespace
Listing 12-67

Create the new method to display the invoice details

  1. 29.

    Amend the Main() method code to call the method as in Listing 12-68.

     
    } while (numberOfClaimsEntered < numberOfClaimsBeingMade);
     vatAmount = CalculateVATAmount(totalOfAllClaims);
     DisplayAllItemsInTheArray();
     Console.WriteLine("The total amount claimed is: " + totalOfAllClaims);
      DisplayInvoiceReceipt(totalOfAllClaims, vatAmount);
    } // End of Main() method
Listing 12-68

Call the method to display the total of all claims

Now we will run the code and use claim values that will make it easy to test if the code works properly. If we make two claim values, as shown in Table 12-3, we can check that our output matches.
Table 12-3

Test data

 

Net amount

VAT amount

Total amount

 

1000

200

1200

 

2000

400

2400

Totals

3000

600

3600

  1. 30.

    Click the File menu.

     
  2. 31.

    Choose Save All.

     
  3. 32.

    Click the Debug menu.

     
  4. 33.

    Choose Start Without Debugging.

     
  5. 34.

    Click in the console window.

     
The console window will appear and ask for the number of entries being made.
  1. 35.

    Type 2 and press the Enter key.

     
The console window will appear and ask the user to input the repair shop id.
  1. 36.

    Type RS000001 and press the Enter key.

     
The console will now ask the user to input the vehicle policy number.
  1. 37.

    Type VP000001 and press the Enter key.

     
The console will now ask the user to input the claim amount.
  1. 38.

    Type 1200.00 and press the Enter key.

     
The console will now ask the user to input the date of the repair.
  1. 39.

    Type 2021/10/01 and press the Enter key.

     
The console window will now ask the user to input the repair shop id.
  1. 40.

    Type RS000001 and press the Enter key.

     
The console will now ask the user to input the vehicle policy number.
  1. 41.

    Type VP001234 and press the Enter key.

     
The console will now ask the user to input the claim amount.
  1. 42.

    Type 2400.00 and press the Enter key.

     
The console will now ask the user to input the date of the repair.
  1. 43.

    Type 2021/10/01 and press the Enter key.

     
The invoice receipt will be displayed as shown in Figure 12-9.

A screenshot of the console window presents the calculation for the vat amount by adding entry 1 of 400 vat and entry 2 of 400 vat.

Figure 12-9

Application output

  1. 44.

    Press any key to close the console window.

     

So now we have added parameter methods. Some of the parameter methods – methods 4, 6, 8, 10, 12, and 13 – are also value methods because they return a value, but method 14 is a void method and a parameter method.

We now have the trio of methods – void, value, and parameter – within our code. Now we are really beginning to see how code modularization works and how it can help by making the methods do one thing, which can be tested. We are also learning to think about using local variables rather than class-level variables.

Method Overloading

In C# we can have more than one method with the same name if we follow a few essential rules:
  • The number of arguments must be different.

    For example, vatAmount(double claimAmount, double vatRate)

    vatAmount(double claimAmount, double vatRate, string vatCode)

  • The types of arguments are different.

    For example, vatAmount(double claimAmount, double vatRate)

    vatAmount(double claimAmount, float vatRate)

  • The order of arguments is different.

    For example, vatAmount(double claimAmount, double vatRate)

    vatAmount(double vatRate, double claimAmount)

Method overloading is a form of polymorphism , different forms of the same object. We will now code a new overloaded method to display a different invoice receipt. The new method, method 15, will accept three arguments. It is a parameter method and it is almost the same code as the last display method.

  1. 45.

    Amend the code to add method 15, as in Listing 12-69.

     
  /******************* METHOD FIFTEEN ******************/
  public static void DisplayInvoiceReceipt(double
  totalValueOfClaimsPassedIn, double vatPassedIn, string
  messagePassedIn)
  {
  Console.WriteLine("********************************");
  Console.WriteLine(" Invoice for vehicle repairs ");
  Console.WriteLine("Nett claim " + (totalValueOfClaimsPassedIn - vatPassedIn) + " ");
  Console.WriteLine("VAT amount " + vatPassedIn + " ");
  Console.WriteLine("Total amount " + totalValueOfClaimsPassedIn + " ");
  Console.WriteLine(messagePassedIn);
  Console.WriteLine("********************************");
 } // End of method DisplayInvoiceReceipt
  } // End of MethodsValue class
} // End of Chapter12 namespace
Listing 12-69

Method with three parameters to display a receipt

  1. 46.

    Amend the Main() method code to call the method as in Listing 12-70.

     
DisplayInvoiceReceipt(totalOfAllClaims, vatAmount);
DisplayInvoiceReceipt(totalOfAllClaims, vatAmount, " " +
 "Thank you for your claims they will be processed today");
} // End of Main() method
Listing 12-70

Call the method to display the new invoice format

  1. 47.

    Click the File menu.

     
  2. 48.

    Choose Save All.

     
  3. 49.

    Click the Debug menu.

     
  4. 50.

    Choose Start Without Debugging.

     
  5. 51.

    Click in the console window.

     
The console window will appear and ask for the number of entries being made.
  1. 52.

    Type 2 and press the Enter key.

     
The console window will appear and ask the user to input the repair shop id.
  1. 53.

    Type RS000001 and press the Enter key.

     
The console will now ask the user to input the vehicle policy number.
  1. 54.

    Type VP000001 and press the Enter key.

     
The console will now ask the user to input the claim amount.
  1. 55.

    Type 1200.00 and press the Enter key.

     
The console will now ask the user to input the date of the repair.
  1. 56.

    Type 2021/10/01 and press the Enter key.

     
The console window will now ask the user to input the repair shop id.
  1. 57.

    Type RS000001 and press the Enter key.

     
The console will now ask the user to input the vehicle policy number.
  1. 58.

    Type VP001234 and press the Enter key.

     
The console will now ask the user to input the claim amount.
  1. 59.

    Type 2400.00 and press the Enter key.

     
The console will now ask the user to input the date of the repair.
  1. 60.

    Type 2021/10/01 and press the Enter key.

     
The invoice receipt will be displayed as shown in Figure 12-10.

A screenshot of the console window depicts the invoice for vehicle repairs and the third parameter in an overloaded method.

Figure 12-10

Application output

  1. 61.

    Press any key to close the console window.

     
So now we have added an overloaded method, method 15. It is overloaded because
  • It has the same name as the DisplayInvoiceReceipt method, method 14.

  • It has three arguments, whereas the other DisplayInvoiceReceipt method, method 14, has two arguments.

Now for something a little different, and I mean different!

C# 7 Local Function

The local function is a feature introduced in C# 7. What we have covered in terms of methods, and methods being created outside the Main() method, applies not just to C# but other languages like Java. We have also seen that it is good practice to modularize our code and use methods that are small and do one thing. This is all part of the concept of clean code and the concept of separation of concern (SOC) . There is also a concept in programming called the SOLID principles , where the S stands for single responsibility, for a class. But maybe we should also think about single responsibility for a method. When we use a Test-Driven Development approach to programming, we are expected to test methods, and we expect those methods to do one thing.

Now, when it comes to methods in C# 7 and above, we can have what is called a local function, which is a function within a method. Sorry. What happened to the “a method should do one thing and we should have separation of concern and clean code that is easy to maintain”? Well, as the developer, we can decide if it is appropriate to use the local function, and we may choose to use it, but we might choose not to use it.

One thing we should remember is that the methods we have used all exist inside a class. We have learned that methods and fields or properties belong to classes and alongside this we can have local variables, which are only accessible within a method and do not need to be accessed in the class or from other classes. “Traditionally,” the method itself is accessible within the class and from outside the class, but C# 7 introduced us to local functions, and C# 8 introduced us to the static local function, both of which we will look at and explore.

A local function is a function declared within an existing method. The local function, as we might deduct from the name “local,” is only accessible within the method, ensuring tight control. Or, if we want to use some “fancy” terminology, the method encapsulates the functionality of the function. We can think of it like this: the local function is a private function to the method it is encapsulated in. When we see the local function, we should immediately associate it with the context of the method. The local function will not have an access modifier, like public, as this would be irrelevant since the local function is only available within the method. An uncomplicated example of a local function is shown in Listing 12-71.
void simpleLocalFunction()
{
  Console.WriteLine($"A local function inside a method");
}
Listing 12-71

Local function

  1. 1.

    Right-click the Chapter12 project.

     
  2. 2.

    Choose Add.

     
  3. 3.

    Choose Class.

     
  4. 4.

    Name the class LocalFunctions.cs.

     
  5. 5.

    Click the Add button.

     
  6. 6.

    Create a Main() method within the class, as this was not produced automatically, and delete the unwanted imports, as in Listing 12-72.

     
Remember the shortcut to create the Main() method is to type svm and then press the Tab key twice .
namespace Chapter12
{
  internal class LocalFunctions
  {
    static void Main(string[] args)
    {
    }// End of Main() method
  } // End of LocalFunctions class
} // End of Chapter12 namespace  
Listing 12-72

Add the Main() method to the class template

  1. 7.

    Right-click the Chapter12 project in the Solution Explorer panel.

     
  2. 8.

    Choose Properties from the pop-up menu.

     
  3. 9.

    Choose the LocalFunctions class in the Startup object drop-down list.

     
  4. 10.

    Close the Properties window.

     

We will now create a static method called CalculateRepairCostIncludingVAT() that will

  • Accept a repair cost.

  • Return a value based on
    • The repair cost

    • The value that will be returned from the local function CalculateVATAmount(), which we will create and which will be passed the variable holding the repair amount.

  1. 11.

    Amend the code to add a CalculateRepairCostIncludingVAT() static method, as in Listing 12-73.

     
    }// End of Main() method
    /*
    Method that takes in the pre-VAT amount and calculates
    the post VAT amount
    */
    public static double CalculateRepairCostIncludingVAT(double
    repairAmountPassedIn)
    {
      return repairAmountPassedIn + CalculateVATAmount(repairAmountPassedIn);
    } // End of calculateRepairCostIncludingVAT method
  } // End of LocalFunctions class
} // End of Chapter12 namespace
Listing 12-73

Add the static method CalculateRepairCostIncludingVAT()

We will now create the local function called CalculateVATAmount, which accepts a value representing the repair cost of type double. Remember this is a local function and is therefore created in an existing method, which in our example is the CalculateRepairCostIncludingVAT() method.
  1. 12.

    Amend the CalculateRepairCostIncludingVAT() method to include our local function, as in Listing 12-74.

     
    public double CalculateRepairCostIncludingVAT(double
            repairAmountPassedIn)
    {
      return repairAmountPassedIn +
            CalculateVATAmount(repairAmountPassedIn);
      /*
      FUNCTION that takes in the pre-VAT amount and
      calculates the VAT amount. This is a local function, a
      function within a method.
      */
      double CalculateVATAmount(double repairAmount)
      {
        double vatamount = repairAmount * 20 / 100;
        return vatamount;
      } // End of local function CalculateVATAmount
    } // End of calculateRepairCostIncludingVAT method
Listing 12-74

Create the local function called CalculateVATAmount

We will now amend the Main() method to

  • Add the method-level variables we need.

  • Call the CalculateRepairCostIncludingVAT() method, passing it the cost of repair value.

  • Display a message to show the total cost.

  1. 13.

    Now add code within the Main() method to add the variables we need, as in Listing 12-75.

     
static void Main(string[] args)
{
  double costOfRepair = 350.00;
  double vatRate = 20;
}// End of Main() method
Listing 12-75

Add the method-level variables within the Main() method

  1. 14.

    Now call the CalculateRepairCostIncludingVAT method, as in Listing 12-76, passing it the variable for the repair cost and assigning the returned value to a new local variable called costOfRepairWithVAT.

     
double costOfRepair = 350.00;
double vatRate = 20;
double costOfRepairWithVAT =  CalculateRepairCostIncludingVAT(costOfRepair);
    }// End of Main() method
Listing 12-76

Call the CalculateRepairCostIncludingVAT method and assign it

  1. 15.

    Now display the value returned from the method call, as in Listing 12-77.

     
   static void Main(string[] args)
    {
      double costOfRepair = 350.00;
      double vatRate = 20;
      double costOfRepairWithVAT = CalculateRepairCostIncludingVAT(costOfRepair);
      Console.WriteLine($"For a repair costing ${costOfRepair:0.00} the cost including VAT at {vatRate}% will be ${costOfRepairWithVAT:0.00}");
    }// End of Main() method
Listing 12-77

Display a message to include the total cost

  1. 16.

    Click the File menu.

     
  2. 17.

    Choose Save All.

     
  3. 18.

    Click the Debug menu.

     
  4. 19.

    Choose Start Without Debugging.

     
Figure 12-11 shows the console window displaying the total cost with the VAT included.

A screenshot of the console window depicts the output. The text reads for a repair costing $350.00 the cost including vat at 20% will be $420.00.

Figure 12-11

Application output having used the local function

C# 8 Static Local Function

While C# 7 introduced the local function, it was further developed in C# 8 with the introduction of the static local function . The concept of a static local function is to ensure that it cannot reference variables from the enclosing method, and if it does, the compiler will complain, throw an error. To make the method static, we add the keyword static to the method “signature.” We will now amend our last code example to
  • Demonstrate a static local function.

  • Show that a class-level static variable can be accessed from within a static local function.

  • Show that outer method variables are not accessible within a static local function.

The steps to show this will be as follows:
  • Move the vatRate variable to the class level and make it private static.

  • Make the Main() method private.

  • Make the CalculateRepairCostIncludingVAT() method private.

  • Make the local function CalculateVATAmount static.

The code shown in the Listing 12-78 has additional and amended comments to help us understand the changes.
  1. 20.

    Amend the code as in Listing 12-78, which applies the steps set out previously.

     
namespace Chapter12
{
  internal class LocalFunctions
  {
    /*
     Make a static class level variable
     We are able to use a static class level variable within
     our local functions and within our static local functions
    */
    private static double vatRate = 20;
    // Make the Main() method private
    private static void Main(string[] args)
    {
      double costOfRepair = 350.00;
      double costOfRepairWithVAT = CalculateRepairCostIncludingVAT(costOfRepair);
      Console.WriteLine($"For a repair costing ${costOfRepair:0.00} the cost including VAT at {vatRate}% will be ${costOfRepairWithVAT:0.00}");
    }// End of Main() method
    /*
     Now we have a private method that takes in private variable
     holding the pre-private VAT amount and the calculates
     the post-private VAT amount
     */
    private static double CalculateRepairCostIncludingVAT(double repairAmountPassedIn)
    {
      return repairAmountPassedIn + CalculateVATAmount(repairAmountPassedIn);
      /*
      FUNCTION that takes in the pre-VAT amount and
      calculates the VAT amount. This is a local function, a
      function within a method.
      This local function is static and we have access to the
      static class level variable vatAmount
      We do not have access to the outer method, in this case
      the Main() method, variables as we would see if we tried
      to use the variable costOfRepair in our formula
      */
      static double CalculateVATAmount(double repairAmount)
      {
        double vatamount = repairAmount * 20 / 100;
        return vatamount;
      } // End of local function CalculateVATAmount
    } // End of calculateRepairCostIncludingVAT method
  } // End of LocalFunctions class
} // End of Chapter12 namespace
Listing 12-78

Static local function accessing static class variable

Running the code again gives us the same output, as in Figure 12-11, but we have applied the use of static local functions and shown how they can access static class-level variables. The other thing to demonstrate is that static local functions cannot access outer method variables.

  1. 21.

    Amend the code, as in Listing 12-79, to make the formula use the variable costOfRepair, which exists in the Main() method, the outer method.

     
   static double CalculateVATAmount(double repairAmount)
    {
     double vatamount = repairAmount * costOfRepair * 20 / 100;
      return vatamount;
    } // End of local function CalculateVATAmount
Listing 12-79

Amend the formula to use the outer method variable

  1. 22.

    Hover over the red underline on the costOfRepair and note that we are being told that this variable does not exist in the current context, as in Figure 12-12.

     

A screenshot highlights a console prompt.

Figure 12-12

Static local function cannot access outer method variable

  1. 23.

    Change the formula back to its original format.

     

C# 10 Null Parameter Checking

We have seen how a method can accept parameters, but what would happen if a parameter was null? Well, C# 10 helps us handle this with the introduction of the null parameter checking .

Add a new class to hold the code for this example.
  1. 1.

    Right-click the project Chapter12 in the Solution Explorer panel.

     
  2. 2.

    Choose Add.

     
  3. 3.

    Choose Class.

     
  4. 4.

    Name the class NullParameterChecking.cs.

     
  5. 5.

    Click the Add button.

     
  6. 6.

    Create a Main() method within the class, as this was not produced automatically, and delete the unwanted imports, as in Listing 12-80.

     
The shortcut to create the Main() method is to type svm and then press the Tab key twice.
namespace Chapter12
{
  internal class NullParameterChecking
  {
    static void Main(string[] args)
    {
    } // End of Main() method
  } // End of NullParameterChecking class
} // End of Chapter12 namespace
Listing 12-80

Create the Main() method

Now we need to set this class as the startup class.
  1. 7.

    Right-click the Chapter12 project in the Solution Explorer panel.

     
  2. 8.

    Choose Properties from the pop-up menu.

     
  3. 9.

    Choose the NullParameterChecking.cs class in the Startup object drop-down list.

     
  4. 10.

    Close the Properties window.

     
  5. 11.

    Amend the code to add a variable to hold a string value representing a vehicle registration and assign it a value, as in Listing 12-81.

     
    static void Main(string[] args)
    {
      string vehicleRegistration = "ABC 1234";
    } // End of Main() method
Listing 12-81

Add a variable to hold the vehicle registration

We will now amend the code to

  • Create a method called DisplayInvoice() , which will accept three values and check if the first value is null:
    • If the value is null, display an error message.

    • If it is not null, display a “receipt.”

  • Call the DisplayInvoice() method and pass it the three values.

  1. 12.

    Amend the code, as in Listing 12-82, to call the DisplayInvoice() method, which we will create next, and pass it three values, the first of which is the variable we set up for the vehicle registration.

     
    static void Main(string[] args)
    {
      string vehicleRegistration = "ABC 1234";
      DisplayInvoice(vehicleRegistration, 10000, 2000);
    } // End of Main() method
Listing 12-82

Call the DisplayInvoice() method passing in three values

  1. 13.

    Amend the code to create the DisplayInvoice() method outside the Main() method, as in Listing 12-83.

     
    } // End of Main() method
    public static void DisplayInvoice(string vehicleRegistration,
      double repairTotal, double vatAmount)
    {
      if (vehicleRegistration == null)
      {
        Console.WriteLine(" Null value error message ");
      } // End of if block
      else
      {
        Console.WriteLine(" Invoice for vehicle repairs ");
        Console.WriteLine("Vehicle registration " +
                            vehicleRegistration + " ");
        Console.WriteLine("Repair amount $" +
                                    repairTotal + " ");
        Console.WriteLine("VAT amount $" +
                                  vatAmount + " ");
      } // End of else block
    } // End of DisplayInvoice() method
  } // End of NullParameterChecking class
} // End of Chapter12 namespace
Listing 12-83

Create the DisplayInvoice() method accepting three values

  1. 14.

    Click the File menu.

     
  2. 15.

    Choose Save All.

     
  3. 16.

    Click the Debug menu.

     
  4. 17.

    Choose Start Without Debugging.

     
Figure 12-13 shows the console window, which displays the receipt.

A screenshot of the console window depicts the invoice for vehicle repairs.

Figure 12-13

Application output receipt

  1. 18.

    Press the Enter key to close the console window.

     
But now let us see what happens when a null value is used.
  1. 19.

    Amend the code to assign null to the variable holding the vehicle registration, as in Listing 12-84.

     
    static void Main(string[] args)
    {
      string vehicleRegistration = null;
      //string vehicleRegistration = "ABC 1234";
      DisplayInvoice(vehicleRegistration, 10000, 2000);
Listing 12-84

Make the variable have a null value

  1. 20.

    Click the File menu.

     
  2. 21.

    Choose Save All.

     
  3. 22.

    Click the Debug menu.

     
  4. 23.

    Choose Start Without Debugging.

     
Figure 12-14 shows the console window displaying the null error message.

A screenshot of the console window depicts the error message. The text reads a null value error message.

Figure 12-14

Application showing that the value is null

  1. 24.

    Press the Enter key to close the console window.

     

C# 10 Null Parameter Checking Approach

In C# 10.0 we can use the ArgumentNullException.ThrowIfNull() method instead of using the if selection construct.
  1. 25.

    Amend the code to use the ArgumentNullException.ThrowIfNull() method on the vehicle registration variable, as in Listing 12-85.

     
namespace Chapter12
{
  internal class NullParameterChecking
  {
    static void Main(string[] args)
    {
      // string vehicleRegistration = "ABC 1234";
      string vehicleRegistration = null;
      DisplayInvoice(vehicleRegistration, 10000, 2000);
    } // End of Main() method
    public static void DisplayInvoice(string vehicleRegistration, double repairTotal, double vatAmount)
    {
      ArgumentNullException.ThrowIfNull(vehicleRegistration);
      Console.WriteLine(" Invoice for vehicle repairs ");
      Console.WriteLine("Vehicle registration " + vehicleRegistration + " ");
      Console.WriteLine("Repair amount $" + repairTotal + " ");
      Console.WriteLine("VAT amount $" + vatAmount + " ");
    } // End of DisplayInvoice() method
  } // End of NullParameterChecking class
} // End of Chapter12 namespace
Listing 12-85

Use the ArgumentNullException.ThrowIfNull() method

  1. 26.

    Click the File menu.

     
  2. 27.

    Choose Save All.

     
  3. 28.

    Click the Debug menu.

     
  4. 29.

    Choose Start Without Debugging.

     
The console window will appear, as shown in Figure 12-15, and display the exception message specifying the parameter causing the problem.

A screenshot of the console window depicts the output.

Figure 12-15

Exception message received when attempting to display the receipt

Chapter Summary

So, finishing this chapter on methods, we now have coded our own
  • Void methods

  • Value methods

  • Parameter methods

  • Overloaded methods

However, we have also used methods in this code that we did not write. In fact, we have been using methods that we did not write from the first program we wrote in this course. The first real line of code we entered was WriteLine();.

WriteLine() is a method. In this line of code, there is no text in the () brackets so no text is written to the console, but a new line is taken. So the WriteLine() method will move to a new line once it prints its content. How does it work? Well, we do not have to worry because we did not write the code and will not have to maintain the method code – it is part of the C# framework. When we go to answer the question, “How does it work?” simply answer it like this: don’t know, don’t care. What this really means is as developers we should not get involved with methods that are developed to help us and have been tested and proved reliable. They work. We just use them to build our application code.

Other examples of methods we did not write but have used in our code include

Write() – Does not move to a new line once it prints its content

ReadLine() – Accepts no arguments

Parse() – Accepts no arguments

nextDouble() – Accepts no arguments

WriteLine("Message") – A parameter method that accepts one argument

Now, thinking about the methods we have created and the methods we have not created but have used, they all have one thing in common, and this commonality will lead us into the next chapter. The common thing about them is that they all live inside a class; they are part of a class. When we code an example like this
     public class MethodsV2
    {
    }
it says that the code contained between the opening curly brace { and the closing curly brace } is within the class. All our code is inside the class, apart from the import statements. So a takeaway from this chapter is that a class contains
  • Methods

  • Variables

We also saw that we can have a local function, a function within a method, and we can even make the function a static function. Finally, we looked at the concept of handling a null parameter being passed to a method by using the ThrowIfNull() method, which accepts the parameter being checked.

We are making great progress in our programming of C# applications and we should be proud of our achievements. In finishing this very important chapter, we are ready to look at classes, and while we have increased our knowledge further, we are advancing to our target.

An illustration of a concentric circle depicts the advancement of the target. The text reads our target is getting closer.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.179.252