---
marp: true
paginate: true
math: mathjax
theme: buutti
title: 6. Methods
---

# Methods

<!-- headingDivider: 5 -->
<!-- class: invert -->

## Overview

* Functions
* Methods
* Parameters
* Return values
* Scope of methods

## What is a function?

* Functions are self-contained modules of code that accomplish a specific task
* Basically, a named block of code that can be executed as many times as we want
  * Instead of writing the same code over and over again, do it only once as a function, and ***call*** it many times
  ```csharp
  void Example()
  {
      Console.WriteLine("Hello World");
  }

  Example(); // calling the function three times
  Example();
  Example();
  ```

### Parameters and returns

* Functions can acquire data, a.k.a. **_parameters_**, from the  **_caller_**
* Functions can return data, a.k.a. its **_return value_**, to the caller
* Defining parameters and return values are optional — not all functions have both, and some have neither!
* Here's a function that takes in one parameter and returns nothing (hence, `void`)
  ```csharp
  void PrintName(string param)
  {
      Console.WriteLine("My name is " + param);
  }
  ```

## Function execution

When a function is called, the program leaves the current section of the code and begins to execute the first line of code inside the function.
1) The program execution comes to the line of code where the function call is
2) The program enters the function
3) Instructions inside the function are executed from top to bottom
  * Remember scopes: The variables defined inside the function are not visible outside the function!
4) The program leaves the function and returns to the point where the function call was and continues the execution
5) If the function returned any data, it can be used where the function was called

### Methods vs functions

* In C#, most functions we see are *__methods__*: functions that are inside a ***class***
* Even the main function is inside a class in C#, so it is a method
  * Classes are explained in [Lecture 7](7-classes-and-objects)
* Here's the earlier function as a method inside the `Program` class
  ```csharp
  class Program
  {
    void PrintName(string param)
    {
      Console.WriteLine("My name is " + param);
    }
  }
  ```


### Calling methods

* A method is executed only when it is *__called__*
* Some methods are already predefined, so we can call them right away
* For example, `Console.WriteLine()` is a method that contains code that prints stuff in the console
  * Instead of writing ourselves all that complex stuff the method contains, we just use the short method call `Console.WriteLine()`
* The use of methods reduces repetitive code, adds modularity and makes designing your programs easier

### Methods: An example

<div class='columns21' markdown='1'>
<div markdown='1'>

```csharp
class Program
{
  void PrintBlock()
  {
    Console.WriteLine("---------------------");
    Console.WriteLine("| This is cool but  |");
    Console.WriteLine("| you wouldn't want |");
    Console.WriteLine("| to write this     |");
    Console.WriteLine("| block of code     |");
    Console.WriteLine("| every time!       |");
    Console.WriteLine("---------------------");
  }

  static void Main(string[] args)
  {
    PrintBlock();
    PrintBlock();
    PrintBlock();
  }
}
```

</div>
<div markdown='1'>

![](imgs/6%20Methods_1.png)

</div>
</div>

---

* In the previous example, we declared a new method called `PrintBlock`
* Then, the method was called three times
  * Each time the entire code inside the method was executed
* Why didn't we have to use the class name the method belonged to, unlike with `Console.WriteLine`?
  * Short answer: Because we called the method inside the class 
* The `void` statement means that the method does not return anything
  * More on that later!

## Parameters

* Sometimes you want to pass data into the method when calling it
* This is done by adding *__parameters__* to the method declaration inside the parentheses:
  ```csharp
  void PrintSum(int val1, int val2)
  {
    int sum = val1 + val2;
    Console.WriteLine("Sum of " + val1 + " and " + val2 + " is " + sum);
  }
  ```
* The values to be passed are set as ***arguments*** in the method call inside the parentheses:
  ```csharp
  PrintSum(2, 5);     // Outputs "Sum of 2 and 5 is 7
  PrintSum(5, 5);     // Outputs "Sum of 5 and 5 is 10
  ```

### Parameters: An example

<div class='columns21' markdown='1'>
<div markdown='1'>

```csharp
static void Main(string[] args)
{
  int centuriesPrinted = 0;
  
  void PrintCentury(int century)
  {
    centuriesPrinted++;
    Console.WriteLine
      ("Current century: " + century);
    Console.WriteLine
      ("Total centuries printed: " + centuriesPrinted);
  }

  for (int i = 0; i < 500; i += 100)
  {
    PrintCentury(i);
  }
}
```

</div>
<div markdown='1'>

![](imgs/6%20Methods_2.png)

Note that this method modifies a value that is ***outside*** the method, which is considered bad practice.

</div>
</div>

## Optional parameters

* You can give a parameter a default value by assigning it in the method declaration
* This makes the parameter optional
  ```csharp
  double CircleArea(double radius = 0)
  {
    double area = Math.PI * radius * radius;
    return area;
  }
  Console.WriteLine(CircleArea());     // This outputs 0
  Console.WriteLine(CircleArea(2));    // This outputs 12,56637...
  ```

## Exercise 1
<!--_class: "exercise invert" -->

1) Write two methods `Sum` and `Difference` that both take in two parameters of type `int`, `value1` and `value2`.
  * `Sum` should print `The sum of <value1> and <value2> is <sum>`
  * `Difference` should print `The difference of <value1> and <value2> is <difference>`
2) Call the methods from the main method multiple times with different arguments.

## Return Values

* The return value of a method is *__returned__* with the `return` keyword:
  ```csharp
  double CircleArea(double radius)
  {
    double area = Math.PI * radius * radius;
    return area;
  }

  double radius = 2;
  double result = CircleArea(radius);
  Console.WriteLine(result);    // Outputs 12,56637...
  ```
* In the first examples, the method declarations started with the `void` keyword, which means that the method doesn't return anything
* Here the method was declared as type `double` — now the method ***must*** return a `double` type variable

### Note about shortening

* The earlier code
  ```csharp
  double radius = 2;
  double result = CircleArea(radius);
  Console.WriteLine(result);
  ```
* can be shortened to
  ```csharp
  double result = CircleArea(2);
  Console.WriteLine(result);
  ```
* and even further into
  ```csharp
  Console.WriteLine(CircleArea(2));
  ```

## Using tuples for multiple return values

* It is possible to return multiple values in the form of a  *__tuple__*:
  ```csharp

  (string, string) FirstAndLastName(string fullname)
  {
    string[] names = fullname.Split(' ');
    return (names[0], names[names.Length - 1]);
  }

  (string first, string last) = FirstAndLastName("Hans \"Dolph\" Lundgren");

  Console.WriteLine($"First name: {first}, last name: {last}");
  // Outputs "First name: Hans, last name: Lundgren"
  ```
* ***Note:*** If only one value from a tuple is needed, you can use a  *__discard__* (`_`)
  ```csharp
  // Only the last name is allocated to a variable
  (_, string lastName) = FirstAndLastName("Arnold Alois Schwarzenegger");
  ```

## Scope of methods

* The variables declared inside a method are *__local variables__*  and only accessible inside the method
  ```csharp
  void ScopeExample()
  {
    // Variable 'a' is only accessible inside of this method
    int a = 10;
    a = 20;         // This works
  }
  a = 30;             // This throws an error
  ```

* Contrastingly, variables declared outside the method are available inside, as seen in an earlier [example](#parameters-an-example)

## Exercise 2
<!--_class: "exercise invert" -->

1) Write a method that takes a string as a parameter and prints the total number of spaces in that string.
2) Without using the `string.Trim()` method, modify the method so that it removes the spaces in a string and returns a new string.

***Hint:*** You can iterate a string just like arrays and lists.

![w:900](imgs/6%20Methods_3.png)

## Exercise 3
<!--_class: "exercise invert" -->

<div class='columns' markdown='1'>
<div markdown='1'>

1) Write a method that takes in a string as a parameter and prints each unique letter in that string.
2) Write a new method that takes a string as a parameter and prints the number of each unique letter in the string.

</div>
<div markdown='1'>

![w:400](imgs/6%20Methods_4.png)

</div>
</div>

## Exercise 4
<!--_class: "exercise invert" -->

* Write a method that takes in a 10-digit number as a parameter and divides individual digits into two arrays of even and odd digits. The method should return both arrays.
* Remember to check that method only accepts numbers!

## Exercise 5
<!--_class: "exercise invert" -->

* Fix this [example](#parameters-an-example) that utilized a bad practice where a variable declared outside the function is modified inside the function.
* So instead, take in the `centuriesPrinted` variable as another parameter, modify it in the function, and then return it.

## Assignments

[Assignments about this topic can be found here](https://gitea.buutti.com/education/academy-assignments/src/branch/master/C%23%20Basics/6.%20Methods)