Methods
Methods let us re-use pieces of code, break down large tasks into a number of smaller tasks, and help us keep our code organized.
Some methods we might want to start collecting for our own personal method libraries are:
- methods to read and validate input from a user
- displaying a list of options
- displaying an array
- formatting outputs a certain way
- and so on
If we write the methods in our method libraries well, we can reuse them over and over and over again!
A few definitions before we get into examples:
- A parameter is a way to pass values or references into a method. Parameters are defined in the method header.
- An argument is the value we supply to the method when we call it.
- Methods can also
return
values to the caller (e.g.ReadLine()
returns astring
), but they do not have toreturn
anything. We call those (methods that don’t return anything)void
methods.
💡 A method may or may not have parameters, and may or may not return something. Any combination is valid! For example:
Console.ResetColor()
has no parameters & avoid
return type.Console.ReadLine()
has no parameters but does return something (astring
).Console.Write("hello")
has a parameter & avoid
return type.Math.Round(3.14159)
has a parameter & returns something (adouble
).
Now that we have our terminology and know all our options, let’s get into the details.
📥 Arguments
Let’s learn a bit more about arguments, what is supplied between the ()
when we call an existing method. Think about arguments as the “input” to a method. Arguments can be passed in 2 ways:
Passing by value:
-
Passing an argument as a value passes a copy of the value. It doesn’t change the original variable/value. For example, when I pass an
int
variable as an argument to the method, that method can use that value, but cannot change the value of that variable.For example, let’s say we’ve created a method called
DoSomething
:static void DoSomething(int inputValue) { Console.WriteLine($"You passed in {inputValue}"); input = 100; }
We can call it by passing in a value for the argument:
DoSomething(5); // prints "You passed in 5."
or
int myNum = 3; DoSomething(myNum); // prints "You passed in 3." // the variable name ("myNum") doesn't need to match the parameter name ("inputValue"): we just need to match the data type. // now, let's see what happens to the value of that variable: Console.WriteLine(myNum); // still 3
Passing by reference:
- This means passing in the actual memory location where that value is stored. This can change the original value of the variable. Arrays are reference types, so they are always passed in as a reference, which means the called method has the ability to view and change its elements.
-
If I want to pass in an
int
(or any other non-reference type) by reference, I need to preface the datatype withref
in both the method header (i.e. the parameter) and the method call (i.e. the argument).Let’s see what that looks like. First, let’s create a method that expects an argument to be passed in as a
ref
erence:static void MultiplyByTwo(ref int j) { j = j * 2; }
Now, let’s call it:
int i = 5; Console.WriteLine($"i was originally {i}"); // i was originally 5 MultiplyByTwo(ref i); Console.WriteLine($"now its value is {i}"); // now its value is 10
- There is a special kind of reference called an
out
reference: this means the called method can change the value of the referenced variable, but it cannot view the current value. To use anout
reference, we preface the datatype without
in both the method header and the method call, instead ofref
.- An example of a
System
method that uses anout
reference isTryParse
:string userInputString; char userInputChar; ... bool isValidInput = char.TryParse(userInputString, out userInputChar);
- An example of a
Bonus content: setting default values for parameters:
We can also set default values for parameters. These default values are used if a corresponding argument is not passed in. ⚠️ Warning: order is important here, if there are multiple parameters!
First, let’s create a method with a default value for a parameter:
static void DoSomething(bool isValid = false) {
// this means: if no value is provided, default to FALSE
if (isValid) {
// do something
}
else {
// do something else
}
}
Now, when we call this method, we can still provide an argument if we want to, but if we don’t provide one, the default value is used instead.
int i = 3;
DoSomething(true);
DoSomething(i == 3); // equivalent to DoSomething(true)
DoSomething(); // defaults to DoSomething(false)
📤 Return types
Another important consideration is whether or not the called method has an “output”: what is its return
type?
Calling a void
method:
void
methods are methods that do not return anything.
For example:
static void DoSomething() {
Console.WriteLine("Something.");
}
can be called like this:
DoSomething();
Calling a method that return
s something:
If a method isn’t void
, we need to ensure we have a return
statement somewhere in that method. Then, the code that calls that method can take that returned value and use it or assign it to a variable.
static int DoSomething() { // this method returns an int
Console.WriteLine("Something.");
return 5;
} /
Now to call this method, I still call the method the same way, but I need to be prepared for the value that will be return
ed. Often, we will save the returned value to a variable to be used later.
int i = DoSomething();
🟰 Remember: the assignment operator (
=
) always takes the value from the right and assigns it to the variable on the left. In other words, the output fromDoSomething
will be “saved” in the poorly-named variablei
.