LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 1718 min read

Methods

Learn how to define and call methods, parameters, return types, and optional parameters in C#.

What is a Method?

A method is a named, reusable block of code that performs a task. Methods let you avoid repeating the same logic throughout a program — a principle often abbreviated as "DRY" (Don't Repeat Yourself), one of the most fundamental ideas in all of software engineering.

static int Add(int a, int b)
{
return a + b;
}
Console.WriteLine(Add(3, 4));
Output

Click Run to see what this code prints.

Real-World Analogy

Think of a method like a vending machine. You provide inputs (money and a selection — the parameters), the machine performs its internal process, and you receive an output (the snack — the return value). You don't need to know how the machine dispenses the snack internally to use it correctly; you just need to know what to put in and what you'll get back.

Parameters & Return Types

A method's signature declares its return type, name, and parameters. Use `void` when a method doesn't return a value at all.

static void Greet(string name)
{
Console.WriteLine($"Hello, {name}!");
}
Greet("Sam"); // no return value

A method can have multiple parameters of different types, and its parameters are entirely independent, local variables that exist only for the duration of that method call.

static double CalculateTotal(double price, int quantity, double taxRate)
{
double subtotal = price * quantity;
return subtotal + (subtotal * taxRate);
}
double total = CalculateTotal(19.99, 3, 0.08);
Console.WriteLine(total.ToString("C")); // $64.77

Expression-Bodied Methods

For a method whose entire body is a single expression, the => arrow syntax removes the need for curly braces and a return keyword entirely — purely a more concise way to write the same thing.

Traditional

csharp
static int Square(int n)
{
return n * n;
}

Expression-Bodied

csharp
static int Square(int n) => n * n;

Optional & Named Parameters

An optional parameter provides a default value used when the caller doesn't supply one — optional parameters must come after all required ones in the parameter list. Named parameters let a caller specify arguments by name rather than strictly by position, useful for clarity or skipping earlier optional parameters.

static void PrintOrder(string item, int quantity = 1)
{
Console.WriteLine($"{quantity}x {item}");
}
PrintOrder("Book"); // uses default quantity
PrintOrder("Pen", 5); // positional
PrintOrder(item: "Notebook", quantity: 2); // named
Output

Click Run to see what this code prints.

The params Keyword

The params modifier lets a method accept any number of arguments of the same type, packed automatically into an array — useful when you don't know in advance how many values will be passed.

static int Sum(params int[] numbers)
{
int total = 0;
foreach (int n in numbers) total += n;
return total;
}
Console.WriteLine(Sum(1, 2, 3)); // 6
Console.WriteLine(Sum(10, 20, 30, 40)); // 100
Console.WriteLine(Sum()); // 0 — even zero arguments is fine

ref and out Parameters

By default, parameters are passed by value — the method receives an independent copy, and changes inside the method don't affect the caller's original variable (for value types; reference types already share the referenced data, as covered in the data types lesson). `ref` and `out` change this, letting a method modify the caller's variable directly. `out` is especially common with TryParse-style methods, since it lets a method both return a success/failure bool AND produce a result value at the same time.

static void Square(ref int number)
{
number = number * number;
}
int value = 5;
Square(ref value);
Console.WriteLine(value); // 25
refout
Must be initialized before calling?YesNo
Method required to assign it?NoYes
Typical useModifying an existing value in placeReturning an additional result (TryParse pattern)

Recursion

A recursive method calls itself, working toward a base case that stops the recursion — a powerful technique for problems that naturally break down into smaller versions of themselves, like calculating a factorial.

static int Factorial(int n)
{
if (n <= 1) return 1; // base case — stops the recursion
return n * Factorial(n - 1); // recursive case
}
Console.WriteLine(Factorial(5)); // 120 (5 × 4 × 3 × 2 × 1)
Always Have a Base Case

A recursive method without a base case that eventually stops the recursion will call itself forever, eventually throwing a StackOverflowException as the call stack fills up — always verify your base case is reachable for every valid input.

Common Beginner Mistakes

Forgetting optional parameters must come last

static void Foo(int a = 1, int b) is a compile error — all parameters after the first optional one must also be optional.

Confusing ref with out

Passing an unassigned variable to a ref parameter is a compile error, since ref requires it to already have a value — use out if the method is meant to produce the initial value.

Missing or unreachable base case in recursion

This leads to a StackOverflowException — always verify recursion moves measurably closer to the base case on every call.

FAQs

`ref` requires the variable to already be initialized before calling, and the method may or may not change it; `out` does not require prior initialization, and the method is required to assign it before returning.

Not directly with a single return type, but tuples (covered as part of pattern matching later in this course) or multiple out parameters both let one method effectively return several values.

No — recursion is often more readable for naturally recursive problems (tree traversal, factorials), but a loop is usually more memory-efficient, since deep recursion consumes stack space per call.

static methods belong to the class itself rather than to any particular object instance — this is explained fully once classes and objects are introduced in an upcoming lesson.

Key Takeaways

  • Methods package reusable logic behind a name, following the DRY (Don't Repeat Yourself) principle.
  • Optional parameters need a default value and must come after required ones; named parameters can be passed in any order.
  • params lets a method accept any number of same-typed arguments as an array.
  • ref/out allow a method to modify the caller's variable directly, with out specifically not requiring prior initialization.
  • Recursive methods must have a reachable base case, or they risk a StackOverflowException.

Summary

Methods are the fundamental unit of reusable logic in C#, with parameters, return values, and modifiers like ref/out/params giving you precise control over how data flows in and out. Next, you'll learn method overloading — defining multiple versions of the same method name.

Next Lesson →

Method Overloading