Methods & Parameters in C#

Methods & Parameters in C#

Methods (also called functions) are the building blocks of C# applications. They allow you to encapsulate logic, improve reusability, and make your code more readable.


1. Access Modifiers: Who Can Use This?

In C#, you can control the visibility of your methods using access modifiers.

ModifierDescription
publicThe method is accessible from any other code in the same project or another project that references it.
private(Default) The method is only accessible within the class or struct in which it is defined.
protectedThe method is accessible within its class and by derived class instances.
internalThe method is accessible within the same assembly (project), but not from other projects.
protected internalAccessible within the same assembly OR from a derived class in another assembly.
private protectedAccessible only within the same class OR by derived classes within the same assembly.

2. Parameter Modifiers: Managing Input & Output

C# provides several keywords to modify how arguments are passed to methods.

1. ref: Pass by Reference

The ref keyword indicates that a variable is passed by reference, not by value. The method can modify the original variable.

public void Increment(ref int value) 
{
    value++; // Modifies the original variable
}

int myNumber = 10;
Increment(ref myNumber);
Console.WriteLine(myNumber); // Output: 11

2. out: Output Parameters

Similar to ref, but the variable must be initialized within the method. It's often used when a method needs to return multiple values.

public void GetCoordinates(out int x, out int y) 
{
    x = 10; // Must be assigned before method exits
    y = 20;
}

GetCoordinates(out int posX, out int posY);

3. params: Variable Number of Arguments

Allows a method to accept a variable number of arguments of the same type.

public int Sum(params int[] numbers) 
{
    return numbers.Sum();
}

int total = Sum(1, 2, 3, 4, 5); // You can pass any number of ints

3. Static Methods: Class-Level Logic

A static method belongs to the class itself, not to a specific instance of the class. You call it using the class name.

public class MathHelper 
{
    public static int Multiply(int a, int b) => a * b;
}

// No need to use 'new'
int result = MathHelper.Multiply(5, 5);

4. Extension Methods: Adding Logic to Existing Types

Extension methods allow you to "add" methods to existing types without modifying the original code. They must be defined in a static class.

public static class StringExtensions 
{
    // The 'this' keyword tells C# this is an extension for 'string'
    public static string ToTitleCase(this string str) 
    {
        if (string.IsNullOrEmpty(str)) return str;
        return char.ToUpper(str[0]) + str.Substring(1).ToLower();
    }
}

string name = "aLEX";
Console.WriteLine(name.ToTitleCase()); // Output: "Alex"

5. Iterators: The yield Keyword

The yield keyword is used to create Iterators (methods that return an IEnumerable). It allows you to return items one-by-one without creating a full collection in memory.

Why use yield?

  1. Memory Efficiency: Great for huge data sets because it only holds one item at a time.
  2. Lazy Evaluation: It only calculates the next item when requested (e.g., in a foreach loop).
public IEnumerable<int> GetEvenNumbers(int max) 
{
    for (int i = 0; i <= max; i++) 
    {
        if (i % 2 == 0) 
        {
            yield return i; // Returns 'i' and PAUSES execution until the next iteration
        }
    }
}

foreach (var num in GetEvenNumbers(10)) 
{
    Console.WriteLine(num); // 0, 2, 4, 6, 8, 10
}

6. Advanced Syntax: Expression-Bodied Members

If a method only has one line of logic, you can use the => (arrow) syntax for brevity.

// Standard
public int Square(int n) { return n * n; }

// Expression-bodied
public int Square(int n) => n * n;

7. Named & Optional Parameters

You can make parameters optional by providing a default value. You can also specify arguments by name to make code clearer.

public void CreateUser(string name, int age = 18, string role = "Guest") 
{
    Console.WriteLine($"{name} ({age}) is a {role}");
}

// Using defaults
CreateUser("Alice"); 

// Using named arguments (skipping 'age')
CreateUser("Bob", role: "Admin");