C# Functions Tutorial

In this tutorial we learn how to group sections of our code to be reused in C#.

We cover how to define and use (call) functions, how to add parameters and return values from a function as well as how to pass parameters by reference and out parameters.

What is a function

A function is one or more statements grouped together for reuse throughout our code.

So far, any functionality we wanted in our application was done inside the Main method. When an application becomes bigger and more complex though, we need to separate our code into smaller sections of logic.

We want one section of code to only be responsible for one task, so we separate the sections into functions.

As an example, let’s create some simple functionality:

Example:
using System;

namespace Methods
{
    class Program
    {
        static void Main(string[] args)
        {
            // number to check
            int num = 5;

            // if the number can be divided by two
            // without a remainder, it's an even num
            if (num % 2 == 0)
                Console.WriteLine("Even number");
            else
                Console.WriteLine("Odd number");

            Console.ReadLine();
        }
    }
}

The example above checks a number to see if it’s odd or even. We can separate all this logic and put it into a function.

But first, let’s see how a function is created.

How to define a function

At it’s most basic, a function consists of a return type, a name, a list of parameters, and at least one statement in it’s body.

Syntax:
returnType identifier (parameterType parameterList)
{
    // body with statements
    return value
}

A function can return a value when it executes. For example, it can do a mathematical calculation and return the result to us. We need to explicitly tell the compiler which type of value the function will return, even when the function doesn’t return a value.

The parameter list is a list of variables that act as inputs for our function. We can use these parameters inside the function.

The return value is the result of the logic, the value that comes back once the function has finished its execution. As mentioned above, a function doesn’t always need to return a value.

Let’s look at an example of the most basic function.

Example:
using System;

namespace Functions
{
    class Program
    {
        static void Main(string[] args)
        { }

        static void PrintMessage()
        {
            Console.WriteLine("Hello World");
        }
    }
}

In the example above, we defined a function called PrintMessage. It’s job is to print a simple message to the console. For now, forget about the static keyword in front of the definition, focus on the rest of the function definition.

Let’s break it down step by step:

  1. When a function doesn’t return a value, we specify its return type as void.
  2. This function doesn’t have any input parameters so there’s nothing inside the parentheses. Even if we don’t have any input parameters, the parentheses must still be there.
  3. Inside the function’s execution block we specify what it must do. In this case it only prints a simple message to the console.

If we run the example above, nothing will happen. The application will run and then exit. The reason is that we’ve defined a function, but we did not use it.

When we define a function, it won’t execute automatically. We have to tell the compiler that we want to use it. This is done in a function call.

We cannot define a function directly inside a namespace. It has to be defined in a class.

How to call (use) a function

To call a function we write it’s name, followed by the parentheses. If our function has any parameters, we specify them between the parentheses.

Syntax:
functionName(parameters);

Let’s call the function that we created in the previous part of this tutorial.

Example:
using System;

namespace Functions
{
    class Program
    {
        static void Main(string[] args)
        {
            PrintMessage();

            Console.ReadLine();
        }

        static void PrintMessage()
        {
            Console.WriteLine("Hello World");
        }
    }
}

In the example above, we call our function inside the Main() function of the program. When we run the application now, it will execute the function and print the message “Hello World”.

The Console.ReadLine() function is included after the function so that the console stays open and we can see the printed message. If we don’t include it, the application will run, print the message and then immediately close again.

The Main() function is the application’s starting point. Every application must have a Main() function that runs the starting code.

How to add parameters to a function

Parameters act as inputs for our function. The function can use those inputs inside its execution block.

Syntax:
returnType identifier (parameterType parameterName)
{
    // function body
}

For each parameter that we specify, we have to include it’s type. The parameter is a temporary variable that will be replaced by whatever we input as an argument.

Let’s create a parameter for our function.

Example:
using System;

namespace Functions
{
    class Program
    {
        static void Main(string[] args)
        {
            PrintMessage("Hello World");

            Console.ReadLine();
        }

        static void PrintMessage(string Message)
        {
            Console.WriteLine(Message);
        }
    }
}

In the example above, we create a string variable called Message. In the execution block we put that variable in the Console.WriteLine() function.

What will happen is that any string value we type between the parentheses will go where the Message variable is in the execution block.

In the function call we write the words “Hello World” between the parentheses. The compiler will take the words and insert them wherever our Message variable appears in the function’s execution block.

When we run the application again now, it still prints out the message “Hello World”.

The great thing is we can change the message now at any time.

Example:
using System;

namespace Functions
{
    class Program
    {
        static void Main(string[] args)
        {
            PrintMessage("Greetings all");

            Console.ReadLine();
        }

        static void PrintMessage(string Message)
        {
            Console.WriteLine(Message);
        }
    }
}

When we run the example above, the message changes from “Hello World” to “Greetings all”.

The value we give to the parameter is called an argument.

We can even call our function multiple times with different messages.

Example:
using System;

namespace Functions
{
    class Program
    {
        static void Main(string[] args)
        {
            PrintMessage("Greetings all");
            PrintMessage("I hope you're having a great day");

            Console.ReadLine();
        }

        static void PrintMessage(string Message)
        {
            Console.WriteLine(Message);
        }
    }
}

In the example above, we call the function twice with different arguments to print out the messages we want.

That’s the whole point of a function, to allow us to reuse a section of code without rewriting all the logic.

We can also have multiple input parameters. When we do, we separate each parameter with a comma in the parentheses.

The function’s parameters can also be of different types.

Example:
using System;

namespace Functions
{
    class Program
    {
        static void Main(string[] args)
        {
            PrintMessage(1, ". Multiple parameters of different types");

            Console.ReadLine();
        }

        static void PrintMessage(int Number, string Message)
        {
            Console.WriteLine(Number + Message);
        }
    }
}

In the function definition above, we have two parameters of different types. In the function call we are required to specify both parameters (without their types).

How to return a value from a function

As mentioned at the start of this tutorial, a function can return a value if it needs to.

We return a value from a function by writing the return keyword, followed by whatever we want to return.

Syntax:
returnType identifier (parameterType parameterList)
{
    // body
    return value
}
Example:
using System;

namespace Functions
{
    class Program
    {
        static void Main(string[] args)
        {
            SumOf(1, 1);

            Console.ReadLine();
        }

        static int SumOf(int a, int b)
        {
            return a + b;
        }
    }
}

In the example above, we have a simple function that calculates the sum of the first and second parameters and returns the answer.

When we run the example, it doesn’t do anything. The function executed, calculated the sum and returned a value, but we didn’t do anything with the returned value.

We can use the returned value directly, or we can store it into a variable.

Example:
using System;

namespace Functions
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine( SumOf(1, 1) );

            Console.ReadLine();
        }

        static int SumOf(int a, int b)
        {
            return a + b;
        }
    }
}

In the example above, we call the function directly in the Console.WriteLine() function to print the returned value to the console.

Example:
using System;

namespace Functions
{
    class Program
    {
        static void Main(string[] args)
        {
            int result = SumOf(1, 1);

            Console.WriteLine("1 + 1 = " + result);
            Console.ReadLine();
        }

        static int SumOf(int a, int b)
        {
            return a + b;
        }
    }
}

In the example above, we store the returned value in a variable before we print it to the console.

Custom isEvenInt() function

At the start of this tutorial we had some functionality that we wanted to place inside a function. You now know enough about functions to be able to do it yourself.

Try to rewrite the functionality into a function. If you get stuck, see our function below.

Example:
bool isEvenInt(int num)
{
    // if the number can be divided by two
    // without a remainder, it's an even num
    if(num % 2 == 0)
        return true;
    else
        return false;
}

The function’s job is to determine if a number is an odd or even number.

Let’s break it down step by step:

  1. We don’t need anything fancy, we can just tell the function to return true if the number is even, or false if the number is odd. So, the return type can be a boolean.
  2. In our parameter list we create a temporary variable called num that will be the number we evaluate to be even or odd.
  3. If the number is even, the function returns true, if the number is odd, it will return false.

Now that we understand the function, let’s run it in our application with a few calls.

Example:
using System;

namespace Methods
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(isEvenInt(5));
            Console.WriteLine(isEvenInt(19));
            Console.WriteLine(isEvenInt(850));
            Console.WriteLine(isEvenInt(3477));

            Console.ReadLine();
        }

        static bool isEvenInt(int num)
        {
            // if the number can be divided by two
            // without a remainder, it's an even num
            if (num % 2 == 0)
                return true;
            else
                return false;
        }
    }
}

In the example above, we call our function directly into the WriteLine() function to print out the results of the logic.

How to pass a parameter by reference

A reference parameter is a reference to a memory location of a variable.

When we pass a parameter by reference, a new storage location in memory is not made, instead we modify the value that already exists in memory (unlike passing a parameter by value which creates and changes a copy).

When declaring a reference parameter we need to specify the ref keyword in front of the type.

Syntax:
returnType identifier(ref type paramIdentifier)
{
    // body with statements
}
Example:
static void SwapWord(ref string word1, string word2)
{
    word1 = word2;
}

In the example above the return type is void, meaning it doesn’t have to return a value. In a normal method we would likely return word1 as a string to do something with.

We don’t need to do that here though because any variable passed into the word1 parameter will be changed to hold the new value.

Think of it as returning the result right into the word1 parameter.

Example:
using System;

namespace Methods
{
    class Program
    {
        static void Main(string[] args)
        {
            string a = "World";

            SwapWord(ref a, "there");

            Console.WriteLine("Hello {0}", a);
            Console.ReadLine();
        }

        static void SwapWord(ref string word1, string word2)
        {
            word1 = word2;
        }
    }
}

Note that when calling a function with a parameter passed by reference, we must use the ref keyword again.

In the example above, the purpose of the function is to change the value of word1 into the value of word2.

The word we want to change is “World”. We are required to assign it to a variable because that variable will hold the changed value (the “returned” value).

The SwapWord() function didn’t have to be stored in a variable because the value of the parameter a is now the result.

In truth, we don’t pass parameters by reference often, but the functionality exists if we want to use it.

How to use out parameters

When we return from a function, we can only return a single value.

If we need to return multiple values, however, we can use output parameters.

Output parameters are similar to reference parameters, the difference is that you can’t use an out parameter to take a value and use it inside the function.

Syntax: define a function with an out parameter
returnType identifier(out type paramIdentifier)
{
    // body with statements
}
Syntax: call a function with an out parameter
identifier(out variableToHoldOutput);
Example:
using System;

namespace Methods
{
    class Program
    {
        static void Main(string[] args)
        {
            int a, b;

            MultiValue(out a, out b, 5, 3);

            Console.WriteLine("5 + 3 = {0}", a);
            Console.WriteLine("5 - 3 = {0}", b);
            Console.ReadLine();
        }

        static void MultiValue(out int add, out int sub, int num1, int num2)
        {
            add = num1 + num2;
            sub = num1 - num2;
        }
    }
}

We couldn’t use the two out parameters to take in a value like we could with ref, they are simply empty holders that will hold the results.

We also need variables to store them into when the function is called.

Summary: Points to remember

  • A function allows us to group sections of code for reuse throughout an application.
  • A function definition consists of a return type, name, parameters and at least one statement.
  • A function that doesn’t return any value can specify its return type as void.
  • A defined function won’t execute automatically, it must be called.
    • When calling a function, we only write it’s name and arguments (if any).
    • A function call is terminated with a semicolon.
  • A function can return a single value by using the return keyword, followed by whatever we want to return.
  • A parameter can be passed by reference which will store any modification to the parameter directly inside of it.
    • When calling a function with ref parameters, we have to specify the ref keyword.
  • We can return multiple values from a function with the out parameter.
    • Unlike a ref parameter, we cannot use an out parameter inside the function itself. They can only store values.