top of page

Lesson 5: Functions And Scopes

Discover a better way to arrange modular or repetitive code. Also get a better understanding of variable scoping. 

Lesson Summary:

Functions

In programming, the concept of a function can take on a variety of names depending on the context. You may see the topic referred to as functions, methods, routines, subroutines, and other names. Though all terms are not necessarily interchangeable, functions and methods in C# are similar enough that we may use either term to refer to this concept (see Lesson FAQ).

At it's basic level, a function is a named routine that does some stuff. A function can be given parameters (called arguments), and it can give back a result (called a return value, or referred to as returning a value). For example, here is a function called GetSum which takes two integers as arguments and returns their sum:

    static int GetSum(int num1, int num2)

    {

        int sum = num1 + num2;

        return sum;

    }

The contents of the function are defined between the braces, {}. 

Note the various components of the function:

In tan we have the function name, GetSum; this, like the variable name, can be a descriptive term of your choice, but it should describe what the function does. 

In red we have the return type. This simply says that the function returns an integer as a result; that is, when you call GetSum, you are expected to get an integer back.

In blue and green we have the first and second arguments, respectively. Each must specify their type (int) and their name (num1 and num2, respectively), just like any other variable. These arguments only exist within this function. They are passed into the function by whatever calls it (more on this in a bit).

In light-green, we have the return statement, which here is returning the result of the sum of num1 and num2. This is the value that we will get back from GetSum.

What about static? For now, let's just include that when defining our functions. In chapter 9 I will show functions that do not use static and in chapter 12 I will describe what static actually does. Describing that concept would be a tad confusing if done right now though.

To use the above function, we can do the following:

   int mySum = GetSum(5, 3);

In this example, we are creating a variable, mySum, and its value will be whatever is returned by our function, GetSum. Note that we pass 2 arguments into GetSum: 5 and 3. These will correspond to the parameters num1 and num2 respectively within the function. After the function GetSum runs, we it will return the sum of 5 and 3, which is 8. Thus, mySum will be set to 8. Note that mySum is an integer, and GetSum is defined to return an integer; be sure that the type of your varible matches the type returned by the function.

Note that the values passed into the function (5 and 3) correspond to the same order in which they are defined in the definition of GetSum (that is, num1 corresponds to 5 and num2 corresponds to 3, as they follow that same order).

void functions and functions with no parameters

A function can be defined with void as the return type to indicate that it does not return any values. void functions are quite common. One example of a void function is a function that does some work and then calls Console.WriteLine(), or maybe writes to a file or something else that does not expect a value to be returned. Later, when we cover classes, we will see even more usecases for void functions.

Also, it is possible for a function to not take any parameters. For example:

     void PrintCurrentTime()

Note that even if it does not take arguments, we still must include the parentheses, (). To call this function, we do the following:

    PrintCurrentTime();

Scope

Scopes refer to the lifetime of variables and types based on where they are created and defined. If you create a variable and it "goes out of scope", that variable ceases to exist. This is best illustrated using an example:

     int outer = 0;

     if (outer == 0)

     {

          int inner = 5;

     }

     Console.WriteLine(outer);

     Console.WriteLine(inner); // this will create a syntax error

As the comment above mentions, the second Console.WriteLine call will lead to a build error. Why is that? Well, even though the variable inner was defined before the WriteLine, it was defined inside the if statement. That is, it's scoped to the block within the {} that follow the if statement. After that block (that is, directly after the right brace, }) the variable inner "goes out of scope" and it no longer exists. However, the variable outer was defined outside of that scope, and in the same scope as the WriteLine statements. By the time the we get to Console.WeiteLine(outer), the variable outer still exists, and has not left scope. You can actually create scopes just by using {} blocks; they don't need to be within things like if statements:

     int outer = 0;

     {

          int inner = 5;

     }

     Console.WriteLine(outer);

     Console.WriteLine(inner); // this will also create a syntax error

Scopes and Functions

Functions have their own scopes. See the following example:

   class Program 

   {

       static void Main(string[] args)

       {

           int num = 5;

           DoStuff();

       }

       static void DoStuff()

       {

           Console.WriteLine(num); // this will also create a syntax error

       }

   }

Despite the fact that the variable num is defined in Main, it does not exist in the scope of DoStuff. To use that value, we must pass it as an argument, as shown here:

   class Program 

   {

       static void Main(string[] args)

       {

           int num = 5;

           DoStuff(num);

       }

       static void DoStuff(int myNum)

       {

           Console.WriteLine(myNum); // this will work

       }

   }

I also changed the name of the parameter in DoStuff to be myNum instead of num just to show that the name of the variable defined in the parameter list (that is, the parameters between the parentheses in the definition of DoStuff) do not matter; only their order does.

Lesson FAQ:

What is the difference between a function and a method?

You might hear me throw the terms around interchangeably. Technically this is probably a bad habbit... but in C# it's not a big deal because the two terms basically represent the same thing.

The difference between a function and a method is that a method is a function member of a class or struct (this will make more sense when we cover classes, in chapter 9). Put more simply, a method is a function that is part of a class (or struct); see that "class Program" thing, within whose brackets {} we put our function? Yeah, our functions are part of the class Program. Technically, the functions we've been using have all been methods. In C++ and other languages you can have functions out in the open, that are not part of a class. In C#, however, all functions have to be somehow defined within a class or struct, loosely speaking. So in C# basically we only have methods.

So why do I call them functions? Because it's a more familiar term, more commonly used in programming to represent this concept, and I prefer not to throw around too much terminology all at once, at least until the topic is familiar. In future lessons I will refer to these more as methods than functions, but this is not a very important distinction in C#.

What is the difference between an argument and a parameter?

To be honest, I often mix up the terms. The parameters are the variables on the function definition. The arguments are the actual values getting passed in. For example:

   int GetSum(int num1, int num2)

In this example, num1 and num2 are parameters.

   int sum = GetSum(5, 3);

In this example, 5 and 3 are the arguments.

Addendum : Function Overloading

Find out about other common (and useful!) ways of declaring functions.

bottom of page