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.
| Modifier | Description |
|---|---|
public | The 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. |
protected | The method is accessible within its class and by derived class instances. |
internal | The method is accessible within the same assembly (project), but not from other projects. |
protected internal | Accessible within the same assembly OR from a derived class in another assembly. |
private protected | Accessible 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?
- Memory Efficiency: Great for huge data sets because it only holds one item at a time.
- Lazy Evaluation: It only calculates the next item when requested (e.g., in a
foreachloop).
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");