C# 11 Methods

The previous chapter began the introduction to object-oriented programming in C# and included the use of methods declared within classes. This lesson will explore C# methods in more detail, including how they are declared and called, passing arguments, and returning results. The topic of passing arguments by reference and value will also be explained.

C# methods are a vital part of writing well-structured and efficient code and provide a way to organize programs while avoiding code repetition. In this chapter, we will look at how methods are declared and used within C#.

What is a method?

A method is a named block of code that can be called upon to perform a specific task. It can be provided data on which to perform the task and can return results to the code that called it. For example, if a particular arithmetic calculation needs to be performed in a C# program, the code to perform the arithmetic can be placed in a method. The Method can be programmed to accept the values on which the arithmetic is to be performed (referred to as parameters) and to return the calculation result. At any point in the program code where the calculation is required, the method is simply called parameter values passed through as arguments, and the result is returned.

Methods vs. Functions

If you are familiar with other programming languages, you may have heard about or used functions in the past. Generally, functions are declared in the same way as methods and fulfill the same purpose. The difference is that methods must be declared within a class, while functions are declared outside of a class. In terms of C#, it is only possible to declare methods within a class, and the concept of functions does not exist.

Parameter or argument?

The terms parameter and argument are often used interchangeably when discussing methods. There is, however, a subtle difference. The values a method can accept when it is called are called parameters. At the point that the method is actually called and passed those values, they are referred to as arguments.

How to declare a C# function

A Swift function is declared using the following syntax:

<access> <return type> <method name>(<para type> <para name>, <para type> <para name>, ...){
    // Method code
}

Explanations of the various fields of the function declaration are as follows:

  • <access> – Defines the level of access to the method from other parts of the code. Valid values are publicprivate, or protected as explained in the previous lesson.
  • <return type> – The data type of the result returned by the function. If the function does not return a result, then this is set to void.
  • <method name> – The name assigned to the method. This is the name by which the method will be referenced when it is called from within the application code.
  • <para type> – The type of the corresponding parameter.
  • <para name> – The name by which the parameter is to be referenced in the method code.
  • Method code – The code statements of the method that perform the work.

As an example, the following method takes no parameters, returns no result, and simply displays a message:

public void sayHello() {
    System.Console.WriteLine("Hello");
}

The following sample function, on the other hand, takes an int and a string as parameters and returns a string result:

public string buildMessage(string name, int count) {
    return($"{name}, you are customer number {count}");
}

Calling a C# method

Once declared, C# methods are called on class instances using dot notaion using the following syntax:

<instance>.<function name>(<arg1>, <arg2>, ... )

Each argument passed through to a method must match the parameters the method is configured to accept. For example, to call the above example method named sayHello which takes no parameters and returns no value, we might write the following code:

class ExampleClass
{

    public class Demo {

        public void sayHello() {
            System.Console.WriteLine("Hello");
        }
    }

    static void Main()
    {
        Demo demo = new Demo();
        demo.sayHello();
    }
}

Handling return values

To call the example method named buildMessage which takes two parameters and returns a result, on the other hand, we might write the following code:

public class Demo {

        public string buildMessage(string name, int count) {
            return($"{name}, you are visitor number {count}");
        }
    }

    static void Main()
    {
        Demo demo = new Demo();
        string message = demo.buildMessage("Mark", 10);
        System.Console.WriteLine(message);
    }
}

In the above example, we have created a new variable called message and then used the assignment operator (=) to store the result returned by the method.

The above example placed parentheses around the return value as follows:

return($"{name}, you are visitor number {count}");

These parentheses are optional, so the following is also a valid use of the return statement:

return $"{name}, you are visitor number {count}";

Passing arguments to a method

Several options are available when calling a method that is expecting arguments. One option, as demonstrated below, is to pass the arguments in the order in which they are declared in the method declaration:

public class Demo {

        public string buildMessage(string name, int count) {
            return($"{name}, you are visitor number {count}");
        }
    }

    static void Main()
    {
        Demo demo = new Demo();
        string message = demo.buildMessage("Mark", 10);
        System.Console.WriteLine(message);
    }
}

When calling a method in this way, the arguments must be passed in the order in which the parameters are declared in the method. Passing arguments to a method using this technique can also make it difficult to understand the purpose of each argument. Both of these issues can be used using the named arguments.

Named arguments

Using named arguments simply involves referencing the parameter names assigned in the method declaration when making calls. For example:

demo.buildMessage(name: "Mark", count: 10);

Since ordering is not important when using named arguments, the following is also a valid call:

demo.buildMessage(count: 10, name: "Mark");

The following example shows named arguments in action:

public class Demo {

    public string buildMessage(string name, int count) {
        return($"{name}, you are visitor number {count}");
    }
}

static void Main()
{
    Demo demo = new Demo();
    string message = demo.buildMessage(name: "Mark", count: 10);
    System.Console.WriteLine(message);

    message = demo.buildMessage(count: 10, name: "Mark");
    System.Console.WriteLine(message);
}

As demonstrated in the code above, the ordering of the arguments no longer matters when making the method call. It is also easier to understand the purpose of each argument being passed to the method.

Optional arguments

C# provides the ability to make arguments optional by designating a default parameter value to be used in the event that the value is not provided as an argument when the method is called. This simply involves assigning the default value to the parameter when the method is declared. The only requirement when working with optional arguments is to place the parameters after any mandatory parameters in the method declaration.

To see optional arguments in action the buildMessage method will be modified so that the string “Customer” is used as a default in the event that a customer name is not passed through as an argument. The method can now be called without passing through a name argument:

public class Demo {

    public string buildMessage(int count, string name = "Customer") {
        return($"{name}, you are visitor number {count}");
    }
}

static void Main()
{
    Demo demo = new Demo();
    string message = demo.buildMessage(count: 10);
    System.Console.WriteLine(message);
}

C# in, out, and ref parameter modifiers

When an argument is passed to a method, it is passed as value. Suppose the code contains an int variable named var to which is assigned the value of 10. The var variable is then passed to a method named DoSomething. In this scenario, only a copy of the value of 10 is passed to the method with no connection to the original var variable. This means that any changes made to the value from within the method will not be reflected in the original variable.

The following code demonstrates this effect in action:

public class Demo {

    public string buildMessage(string name, int count) {
        return($"{name}, you are visitor number {count}");
    }
}

static void Main()
{
    Demo demo = new Demo();
    string message = demo.buildMessage(name: "Mark", count: 10);
    System.Console.WriteLine(message);

    message = demo.buildMessage(count: 10, name: "Mark");
    System.Console.WriteLine(message);
}

The code in the Main method declares a variable and assigns to it a value of 20. Before calling the method, the current value of var is displayed. The variable is then passed as an argument to the DoSomething method where it is assigned a value of 10. When control is returned to the Main method, the value assigned to the var variable is output once again.

As the output shows, the value assigned to the var variable was changed by the method.

To allow the value assigned to the variable to be changed within the method, we need to pass the variable by reference.

Passing by reference means that instead of passing the underlying value, we are instead passing a reference to the location in memory where the variable stores its value. Any changes made within the method will be made to the variable’s value.

A variable is passed by reference using the ref modifier both when declaring the parameter in the method and when calling the method as shown below:

public class Demo {

    public void DoSomething(ref int var) {
        var = 10;
    }
}

static void Main()
{
    int var = 20;
    Demo demo = new Demo();

    System.Console.WriteLine($"Before method call var = {var}");
    demo.DoSomething(ref var);
    System.Console.WriteLine($"After method call var = {var}");
}

As shown by the output, the value assigned to var changes from 20 to 10 after the method call.

Another modifier available when calling methods is the out parameter. When using the ref parameter, whether the variable value is changed within the method is entirely optional. To force the change to the variable within the method use the out modifier in place of the ref.

The out modifier is generally used to force the method to initialize a variable when it is null at the point it is passed. For example:

public class Demo {

    public void DoSomething(out string var) {
       var = "Hello";
    }
}

static void Main()
{
    string var;
    Demo demo = new Demo();

    System.Console.WriteLine($"Before method call var = {var}");
    demo.DoSomething(out var);
    System.Console.WriteLine($"After method call var = {var}");
}

The final modifier to be covered is the in modifier. This modifier also sends the variable to the method by reference but prevents that reference from being changed from within the method.


Categories