← Open in the full interactive course (progress tracking, search & more)

Reusable blocks of code that make programs modular and maintainable.

Imagine you're writing a program that needs to calculate the area of a circle in ten different places. Without methods, you'd copy the same formula ten times — and if you ever needed to fix a mistake, you'd have to find and change all ten copies.

Now imagine if you could write that formula once, give it a name like CalculateCircleArea, and then simply call that name wherever you need it. That's exactly what methods provide: reusability, organization, and maintainability.

Methods are the foundation of structured programming in C#. Every C# program is built from methods — from the simplest Console.WriteLine to the most complex business logic.

In this lesson, you'll learn what methods are, how to define and call them, what happens behind the scenes, and how to design them well.

What Is It?

The Simple Explanation

A method is a named block of code that performs a specific task. You can call (invoke) it from other parts of your program, and it can optionally return a result.

The Technical Definition

In C#, a method is a member of a class or struct that contains a sequence of statements. It has a signature that includes:

Methods can be:

Method Type Declaration Called On
Instance public int Add(int a, int b) { ... } An object instance
Static public static int Add(int a, int b) { ... } The type itself
Expression-bodied public int Add(int a, int b) => a + b; Same as instance/static
Local function int Add(int a, int b) => a + b; inside a method Within the enclosing method
Extension public static int Double(this int x) => x * 2; Any instance of the extended type

Why Does It Exist?

The Problem

As programs grow, several problems arise:

The Solution

Methods solve these problems by allowing you to:

The key insight

Methods turn what the code does into what the code means. Instead of reading a pile of calculations, you read CalculateTotal() or SendEmail() and immediately understand the intent.

Big Picture

Methods organize a program into a hierarchy of well-defined operations. Here's how a typical application might be structured:

PROGRAM AS A SET OF METHODS
Main()
  • Entry point — orchestrates overall flow
ProcessOrder()
  • High-level business operation
ValidateOrder() · CalculateTotal() · SaveToDatabase()
  • Each method does one specific job

This layered approach keeps the code manageable and intuitive. Each method is like a LEGO brick that fits into a larger construction.

How It Works

Let's trace the execution of a method call step by step.

Step 1 — Method Declaration

public static int Add(int a, int b)
{
    int sum = a + b;
    return sum;
}

The method signature specifies public static, return type int, name Add, and parameters int a and int b. The body calculates and returns the sum.

Step 2 — Method Invocation

int result = Add(3, 5);

Arguments 3 and 5 are passed to the method.

Step 3 — Parameter Passing

The values are copied into the parameters a and b. For value types, this is a copy; for reference types, the reference is copied (not the object).

Step 4 — Method Body Execution

The statements inside the method execute in order. Local variables like sum are created on the stack.

Step 5 — Return

The return statement sends the result back to the caller. If the method is void, it simply returns control without a value.

Step 6 — Caller Resumes

Execution continues from the point after the method call. The returned value can be assigned to a variable or used in an expression.

Simple Example

using System;

class Calculator
{
    // Instance method
    public int Add(int a, int b)
    {
        return a + b;
    }

    // Static method
    public static int Multiply(int a, int b)
    {
        return a * b;
    }

    // Expression-bodied method
    public double Divide(double a, double b) => a / b;

    // Method with no return value
    public void PrintResult(string operation, double value)
    {
        Console.WriteLine($"{operation}: {value}");
    }
}

class Program
{
    static void Main()
    {
        var calc = new Calculator();
        int sum = calc.Add(3, 5);              // instance method call
        int product = Calculator.Multiply(4, 6); // static method call

        calc.PrintResult("Sum", sum);
        calc.PrintResult("Product", product);
    }
}

Code → Meaning → Result

Real-World Example

Consider a banking application that needs to transfer money between accounts. Each step is a method:

using System;

public class BankAccount
{
    public string AccountNumber { get; set; }
    public decimal Balance { get; private set; }

    public BankAccount(string accountNumber, decimal initialBalance)
    {
        AccountNumber = accountNumber;
        Balance = initialBalance;
    }

    // Method to deposit money
    public void Deposit(decimal amount)
    {
        if (amount <= 0)
            throw new ArgumentException("Amount must be positive");
        Balance += amount;
    }

    // Method to withdraw money
    public void Withdraw(decimal amount)
    {
        if (amount <= 0)
            throw new ArgumentException("Amount must be positive");
        if (amount > Balance)
            throw new InvalidOperationException("Insufficient funds");
        Balance -= amount;
    }

    // Method to transfer to another account
    public void TransferTo(BankAccount destination, decimal amount)
    {
        if (destination == null)
            throw new ArgumentNullException(nameof(destination));
        if (destination.AccountNumber == AccountNumber)
            throw new InvalidOperationException("Cannot transfer to same account");

        Withdraw(amount);
        destination.Deposit(amount);
    }
}

Each method encapsulates a single business rule. TransferTo uses other methods (Withdraw, Deposit) — a great example of building complex operations from simpler ones.

Analogy

Methods as Kitchen Recipes

A method is like a recipe: it has a name ("Chocolate Cake"), a list of ingredients (parameters), and a set of steps (method body). Once the recipe exists, anyone can follow it and get the same result.

Calling a method is like saying "Make the chocolate cake" to a chef. You don't need to know the steps; you just need the result.

A method that calls another method is like a recipe that says "prepare the frosting using the frosting recipe." You compose simpler recipes to build more complex dishes.

This analogy captures reusability and abstraction: once the recipe is correct, you can use it forever.

Under the Hood

What actually happens in the CLR when a method is called?

INTERNAL VIEW
1. CALL INSTRUCTION
2. STACK FRAME CREATION
3. EXECUTION
4. RETURN AND CLEANUP
5. INLINING (OPTIMIZATION)

Common Confusion

1. Parameters vs Arguments

Parameters are the variables defined in the method declaration. Arguments are the actual values passed to the method when calling it.

// Parameter: a and b
public int Add(int a, int b) => a + b;

// Arguments: 3 and 5
int sum = Add(3, 5);

2. Static vs Instance Methods

Instance methods require an object and can access instance fields. Static methods belong to the type and can only access static members.

class MyClass
{
    public int instanceField = 5;
    public static int staticField = 10;

    public void InstanceMethod() { /* can access both instanceField and staticField */ }
    public static void StaticMethod() { /* can access only staticField */ }
}

3. void vs Return Type

A void method does not return a value; a method with a return type must use return with a compatible value.

4. Passing by Value vs by Reference

By default, value types are passed by value (a copy). With ref or out, you can pass by reference, allowing the method to modify the caller's variable. Reference types pass the reference by value; the object itself can be modified, but the reference cannot be reassigned unless using ref.

5. Method Overloading

You can have multiple methods with the same name but different parameter lists (overloading). The compiler selects the best match based on arguments.

public int Add(int a, int b) => a + b;
public double Add(double a, double b) => a + b;

Common Mistakes

Mistake 1 — Not returning a value from a non-void method

A method with return type int that lacks a return statement on all code paths causes a compile error.

Ensure every path returns a value or throws an exception.

Mistake 2 — Forgetting to use out or ref when modifying primitive parameters

Attempting to change a parameter's value inside a method and expecting the caller to see the change without ref.

Use ref for value types if you need to modify the caller's variable. Better yet, return the new value instead of using ref when possible.

Mistake 3 — Using too many parameters

A method with 10+ parameters is hard to use and understand.

Group related parameters into a class or struct, or use a parameter object.

Mistake 4 — Not validating method arguments

Assuming parameters are always valid can lead to subtle bugs and exceptions later.

Use guard clauses to validate arguments at the start of the method and throw ArgumentException or ArgumentNullException.

Mistake 5 — Long methods that do too many things

A method with hundreds of lines becomes impossible to test and debug.

Follow the Single Responsibility Principle: each method should do one thing and do it well. Extract sub-methods when needed.

When Should I Use It?

You should create methods whenever you identify:

When a method might be overkill:

Mental Model

Method = a named block of reusable code
Signature = return type + name + parameters
Call = invoke the method with arguments
Return = send a result back (or void)

Remember:
· Methods encapsulate one idea
· Prefer returning values over ref/out
· Static methods don't need an instance
· Local functions can capture variables from the enclosing method

Key Takeaway


Check Your Understanding

You've seen how methods work, why they're important, and how to design them well. Let's test your understanding.

1. What is the key difference between parameters and arguments in a method?

Show answer

Correct: B

Why B is correct: Parameters are defined in the method signature (e.g., int a, int b). Arguments are the values supplied during the method call (e.g., 3, 5).

Why A is incorrect: The definitions are reversed.

Why C is incorrect: They are related but distinct concepts.

Why D is incorrect: This distinction has nothing to do with value vs reference types.

Reinforcement: Remember: parameters are the placeholders; arguments are the real data.

2. Which of the following correctly defines a static method that returns an integer and takes two integer parameters?

Show answer

Correct: B

Why B is correct: The static keyword indicates it belongs to the type. Return type is int, and parameters are int a and int b. Expression-bodied syntax => a + b returns the sum.

Why A is incorrect: Missing static; it's an instance method.

Why C is incorrect: Return type is void, but expression returns a value — this won't compile.

Why D is incorrect: b is missing its type; C# requires each parameter to have a type.

Reinforcement: A static method is declared with the static modifier and must have a return type (or void).

3. What is the output of the following code?

void ChangeValue(int x)
{
    x = 10;
}

int number = 5;
ChangeValue(number);
Console.WriteLine(number);
Show answer

Correct: A

Why A is correct: The method receives a copy of number (value type passed by value). Changing x inside the method does not affect the original number variable.

Why B is incorrect: To change the caller's variable, you would need to pass by reference using ref.

Why C is incorrect: The code is valid.

Why D is incorrect: No runtime error occurs.

Reinforcement: Value types are passed by value by default; changes inside the method are local.

4. Which of the following is a valid overload of the method public int Add(int a, int b)?

Show answer

Correct: C

Why C is correct: Overloading requires a different parameter list (type or count). double a, double b is different from int a, int b, so it's a valid overload.

Why A is incorrect: Renaming parameters does not change the signature.

Why B is incorrect: Return type alone is not part of the signature; this would cause a duplicate definition.

Why D is incorrect: Adding static does not change the parameter list; it would conflict with the instance method.

Reinforcement: Method overloading is based on the method name and parameter list; return type and modifiers don't count.

5. When should you prefer a static method over an instance method?

Show answer

Correct: B

Why B is correct: Static methods belong to the type and cannot access instance fields. If a method doesn't depend on object state, making it static improves clarity and testability.

Why A is incorrect: Instance methods can access instance fields; static methods cannot.

Why C is incorrect: Polymorphism requires instance methods (virtual/abstract); static methods are not polymorphic.

Why D is incorrect: Static methods cannot be overridden.

Reinforcement: Use static methods for utility or stateless operations; use instance methods for behaviour tied to object state.

You've mastered methods — the building blocks of maintainable C# code!


dotnetmadeeasy.com — Learn C# and .NET, the right way.