Skip to main content

    Lesson 6 • Intermediate Track

    Methods

    By the end of this lesson you'll be able to package code into reusable, named methods — passing in parameters, handing back results with return, giving parameters sensible defaults, and overloading one name for several jobs. This is how real programs stay organised instead of becoming one giant block of code.

    What You'll Learn

    • Define methods with parameters and call them with arguments
    • Return a value with return, or use void for actions with no result
    • Use optional (default), named, and params arguments
    • Hand back multiple values with out parameters (the TryParse pattern)
    • Overload one method name for different parameter signatures
    • Write expression-bodied methods and understand variable scope

    💡 Real-World Analogy

    A method is like a kitchen appliance. A blender takes ingredients (parameters), processes them, and hands back a smoothie (the return value) — and you never have to know how the motor works inside (that's abstraction). The label on the button is the method name; what you drop in is the arguments. Overloading is a multi-function cooker: one name on the front, but it bakes, steams, or pressure-cooks depending on which settings (parameter types) you give it. Once you've built an appliance, you press its button as many times as you like — that's the whole point of a method.

    📊 Method Syntax Reference

    FeatureSyntaxMeaning
    Void methodstatic void Name()Does something, returns nothing
    Return valuestatic int Name()Must return an int
    Expression bodystatic int F() => expr;One-liner shorthand for return
    Optional paramvoid F(int x = 5)Uses 5 if the caller omits it
    Params arrayvoid F(params int[] n)Any number of arguments
    Out parameterbool F(out int r)Hands back an extra value
    Named argsF(name: "Bo", age: 9)Pass by name, any order

    Parameter = the placeholder named in the method's definition. Argument = the actual value you pass in when you call it. Same slot, two words — they trip everyone up at first.

    1. Defining & Calling Methods

    A method has a return type (what it gives back), a name, and a list of parameters (its inputs). Use void when it just does something with no result to report; use a type like int, string or double when it should hand a value back with return. Simple one-liners can use the expression-bodied form => instead of { return ...; }. Read this worked example first, run it, then you'll finish one yourself.

    Worked example: void, return & expression-bodied

    Read every comment, run it, and check each result matches.

    Try it Yourself »
    C#
    using System;
    
    class Program
    {
        // A void method DOES something but returns nothing.
        // Shape:  static void Name(parameters) { ... }
        static void Greet(string name)
        {
            Console.WriteLine($"Hello, {name}! 👋");   // prints, returns nothing
        }
    
        // A method with a RETURN TYPE (int) must hand a value back.
        //   int Add(int a, int b)
        //   |--|  |-| |--------|
        //  return  name  parameters (the inputs)
        static int Add(int a, int b)
        {
            return a + b;  
    ...

    Your turn. The method below is meant to return the area of a rectangle, but the return type and the return expression are blank. Fill in the two ___ blanks using the hints, then run it.

    🎯 Your turn: complete a method that returns a value

    Fill in the return type and the return expression, then check the area is 20.

    Try it Yourself »
    C#
    using System;
    
    class Program
    {
        // 🎯 YOUR TURN — fill in the blanks marked with ___ then run it.
        // Goal: finish a method that RETURNS the area of a rectangle.
    
        // 1) The method must hand back a number, so its return type is int.
        static ___ RectangleArea(int width, int height)   // 👉 return type: int
        {
            // 2) Multiply the two parameters and send the answer back.
            return ___;            // 👉 the expression: width * height
        }
    
        static void Main()
        {
       
    ...

    2. Parameters — Optional, Named, Params & Out

    Optional parameters carry a default value, so callers can leave them off (they must come after all required parameters). Named arguments let you pass values by name in any order, which makes calls self-documenting. params accepts any number of arguments as an array. And out lets a method hand back more than one value at once — it's exactly how int.TryParse returns both a success flag and the parsed number.

    Worked example: optional, named, params & out

    See default values, named calls, variable-length params, and out parameters in action.

    Try it Yourself »
    C#
    using System;
    
    class Program
    {
        // OPTIONAL parameters have a default. They MUST come after required ones.
        static void PrintMessage(string msg, int times = 1, string prefix = "→")
        {
            for (int i = 0; i < times; i++)
                Console.WriteLine($"{prefix} {msg}");   // repeats 'times' lines
        }
    
        // params — accept ANY number of arguments as an array.
        static int Sum(params int[] numbers)
        {
            int total = 0;
            foreach (int n in numbers) total += n;
          
    ...

    Now you try. The method below greets someone, with a greeting that should default to "Hello". Fill in the default value and the two calls — one using the default, one overriding it.

    🎯 Your turn: parameters with a default value

    Give the greeting a default, call it once with and once without, then check both lines.

    Try it Yourself »
    C#
    using System;
    
    class Program
    {
        // 🎯 YOUR TURN — fill in the blanks marked with ___ then run it.
        // Goal: greet someone, with an OPTIONAL greeting that defaults to "Hello".
    
        // 1) Give 'greeting' a default value of "Hello" so callers can skip it.
        static void Welcome(string name, string greeting = ___)   // 👉 default: "Hello"
        {
            Console.WriteLine($"{greeting}, {name}!");
        }
    
        static void Main()
        {
            // 2) Call Welcome with ONLY a name — it should use the
    ...

    3. Overloading, Scope & Recursion

    Method overloading means giving several methods the same name but different parameter types or counts — the compiler picks the right one from the arguments you pass (note: the return type alone can't tell two overloads apart; the parameters must differ). Scope is where a name is visible: a variable declared inside a method is local to it and disappears when the method ends. Recursion is a method that calls itself — handy for problems that shrink toward a base case that stops the recursion.

    Worked example: overloading, scope & recursion

    Watch the compiler choose overloads by signature, and see a recursive factorial unwind.

    Try it Yourself »
    C#
    using System;
    
    class Program
    {
        // OVERLOADING — same name, DIFFERENT parameters. The compiler
        // picks the version that matches the arguments you pass.
        static int Multiply(int a, int b) => a * b;
        static double Multiply(double a, double b) => a * b;
        static int Multiply(int a, int b, int c) => a * b * c;
    
        // SCOPE: 'a', 'b', 'c' above are LOCAL — they only exist inside
        // their own method. A variable made in Main can't be seen here.
    
        // RECURSION — a method that cal
    ...

    🔎 Deep Dive: passing by value vs ref / out

    By default a method gets a copy of the value you pass (this is "pass by value"). Changing the parameter inside the method does not change the caller's variable. To let a method change the caller's variable, use ref (in and out) or out (out only — the method must assign it before returning).

    static void AddOne(int n)      { n++; }            // works on a COPY
    static void AddOneRef(ref int n) { n++; }          // works on the ORIGINAL
    
    int x = 5;
    AddOne(x);        // x is still 5  (the copy was changed, not x)
    AddOneRef(ref x); // x is now 6    (ref reached back to the original)

    Use out when a method needs to produce an extra result (like TryParse). Use ref when it needs to read and update an existing value. Most of the time, prefer returning a value (or a tuple) over ref — it's clearer.

    Putting It Together: a Tiny Shopping Cart

    Here's a small program that uses everything from this lesson at once — a params method to total any number of prices, an expression-bodied method with an optional tax rate, a void printer, and a named argument to override the default. You understand every line now.

    Worked example: shopping cart

    Change the prices or the tax rate and watch the subtotal and total update.

    Try it Yourself »
    C#
    using System;
    
    class Program
    {
        // === Tiny shopping cart — every method here uses this lesson's skills ===
    
        // Returns a value; uses an OPTIONAL tax rate parameter.
        static decimal WithTax(decimal amount, decimal rate = 0.20m)
            => amount + amount * rate;          // expression-bodied, returns decimal
    
        // params — sum any number of item prices into a subtotal.
        static decimal Subtotal(params decimal[] prices)
        {
            decimal sum = 0;
            foreach (decimal p in pr
    ...

    Notice how each method does one job and has a name that says what it does. That's the habit to build: small, well-named methods read like a description of the program.

    Pro Tips

    • 💡 One method, one job: if a method is over ~20 lines or does several things, split it. Small methods are easier to name, test, and reuse.
    • 💡 Name methods as verbs: CalculateTotal, IsValid, GetUser — the name should say what it does or returns.
    • 💡 Prefer returning a value (or tuple) over out: static (int min, int max) Range(int[] a) reads more cleanly than two out parameters.
    • 💡 Use expression bodies for one-liners: static bool IsEven(int n) => n % 2 == 0; is clean and clear.
    • 💡 Keep parameter lists short: more than three or four parameters usually means the data belongs together in a class or record (next lesson).

    Common Errors (and the fix)

    • "CS0161: not all code paths return a value": a method with a return type must return on every path. If you have if (x) return a; with no final return, add a fallback return after the if.
    • "CS1501: No overload for method 'X' takes N arguments": you called the method with the wrong number of arguments. Check the definition — e.g. Add(5) when Add(int a, int b) needs two.
    • "CS0029: Cannot implicitly convert type 'string' to 'int'": you returned the wrong type. A static int GetName() that returns text won't compile — match the return type to what you actually return (here, change it to string).
    • "CS0127: Since 'X' returns void, a return keyword must not be followed by an object expression": a void method tried to return a value. Either drop the value (return; on its own is fine for an early exit) or change the method's return type.
    • "CS1737: Optional parameters must appear after all required parameters": you put a defaulted parameter before a required one. Reorder so all = default parameters come last.
    • Overloading by return type only: two methods with the same name and parameters but different return types won't compile — the parameters must differ.

    📋 Quick Reference

    TaskCodeNotes
    Action, no resultstatic void Log(string m)No return value
    Return a valuestatic int Add(int a, int b)return a + b;
    One-linerstatic int Sq(int n) => n * n;Expression body
    Default valuevoid F(int x = 0)Optional param (last)
    Call by nameF(x: 5)Named argument
    Many argumentsint Sum(params int[] n)Sum(1, 2, 3)
    Extra outputbool TryX(out int r)Assign r before return
    OverloadF(int) / F(double)Params must differ

    Frequently Asked Questions

    Q: What's the difference between a parameter and an argument?

    A parameter is the named placeholder in the method's definition — int a in Add(int a, int b). An argument is the real value you pass when you call it — the 5 in Add(5, 3). Definition side = parameter; call side = argument.

    Q: When should I use void vs a return type?

    Use void when the method's job is to do something (print, save, send) and there's no answer to hand back. Use a return type when the caller needs a result — a total, a grade, a true/false. If you find yourself printing inside a method and the caller also wants the value, return it instead and let the caller print.

    Q: What's the difference between out and ref?

    Both let a method change the caller's variable. out is "output only" — the method must assign it before returning, and the caller doesn't need to set it first (used by TryParse). ref is "in and out" — the value must be set before the call and the method can read and change it.

    Q: Why won't C# let me overload by return type?

    When you write Multiply(2, 3), the compiler chooses the overload from the arguments, not from what you do with the result. Two methods that differ only in return type would be ambiguous, so C# requires the parameter lists to differ.

    Mini-Challenge: Write a Max Method

    No blanks this time — just a brief and an outline. Write a method static int Max(int a, int b) that returns the larger of its two arguments, then call it on a few pairs in Main and print the results. Run it and check your output against the expected lines in the comments.

    🎯 Mini-Challenge: int Max(int a, int b)

    Write the method yourself, call it on three pairs, and match the expected output.

    Try it Yourself »
    C#
    using System;
    
    class Program
    {
        // 🎯 MINI-CHALLENGE: write a Max method
        // 1. Write a method  static int Max(int a, int b)
        //    that RETURNS the larger of the two numbers.
        //    (Hint: an if statement, or the ternary  a > b ? a : b)
        // 2. In Main, call it on a few pairs and print the results.
        //
        // ✅ Expected output:
        //    Max(3, 9) = 9
        //    Max(12, 4) = 12
        //    Max(7, 7) = 7
    
        // write your Max method here
    
        static void Main()
        {
            // ca
    ...

    🎉 Lesson Complete

    • ✅ A method bundles code under a name with parameters (inputs) you call using arguments
    • void methods perform actions; typed methods hand a value back with return
    • ✅ Expression-bodied syntax (=>) is shorthand for a one-line return
    • ✅ Parameters can be optional (default), named, or params for any count
    • out hands back extra values; ref reads and updates the caller's variable
    • Overloading reuses a name across different parameter signatures; scope keeps locals private to their method
    • Next lesson: Object-Oriented Programming — group data and methods together into classes and objects

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service

    Install LearnCodingFast

    Learn faster with the app on your home screen.