Skip to content

C# - Methods

A method is a reusable block of code that performs a specific task. Methods are the building blocks of C# programs, allowing you to organize your code into logical, manageable units. Every C# application starts execution from a special method called Main.

Using methods involves two steps:

  • Defining the method: Describing what the method does, what it needs (parameters), and what it returns.
  • Calling the method: Executing the code inside the method.

The syntax for defining a method in C# is as follows:

<Access_Specifier> <Return_Type> <Method_Name>(<Parameter_List>)
{
// Method Body
// Code to perform the task
}
  • Access Specifier: Determines visibility (e.g., public, private). public methods can be called from anywhere, while private methods can only be called from within the same class.
  • Return Type: The data type of the value the method sends back. If the method doesn’t return a value, use the void keyword.
  • Method Name: A descriptive name for the method, following PascalCase conventions (e.g., CalculateSum).
  • Parameter List: A comma-separated list of input variables for the method, enclosed in parentheses. If there are no parameters, you use empty parentheses (). Each parameter has a type and a name.
  • Method Body: The code block containing the statements that execute when the method is called.
public class Greeter
{
// A simple method with no parameters and no return value
public void SayHello()
{
Console.WriteLine("Hello, World!");
}
// A method with parameters and a return value
public int Add(int a, int b)
{
int sum = a + b;
return sum;
}
}

To call a method, you need an instance of the class it belongs to (unless it’s a static method). You then use the dot (.) operator.

using System;
public class Greeter
{
public void SayHello() => Console.WriteLine("Hello, World!");
public int Add(int a, int b) => a + b;
}
public class Program
{
public static void Main(string[] args)
{
// Create an instance of the Greeter class
var greeter = new Greeter();
// Call the SayHello method
greeter.SayHello(); // Output: Hello, World!
// Call the Add method and store the result
int result = greeter.Add(10, 5);
Console.WriteLine($"The sum is: {result}"); // Output: The sum is: 15
}
}

For methods that contain only a single expression, you can use a more concise syntax called an expression-bodied member.

public class Calculator
{
// Traditional method body
public int Multiply(int x, int y)
{
return x * y;
}
// Same method using an expression body
public int Add(int x, int y) => x + y;
}

You can define a method inside another method. These are called local functions and are only visible within the containing method. They are useful for helper routines that don’t need to be exposed elsewhere.

public void ProcessOrders(IEnumerable<Order> orders)
{
foreach (var order in orders)
{
// ... some logic ...
Log(order.Id, "Processing");
// ... more logic ...
Log(order.Id, "Completed");
}
// Local function is only accessible inside ProcessOrders
void Log(int orderId, string message)
{
Console.WriteLine($"[{DateTime.Now:T}] Order {orderId}: {message}");
}
}

C# provides several ways to pass parameters to methods, each with different behavior.

KeywordDescription
(none)Pass by value. A copy of the argument is passed. Changes to the parameter inside the method do not affect the original variable.
refPass by reference. A reference to the argument is passed. Changes to the parameter inside the method do affect the original variable. The variable must be initialized before being passed.
outPass by reference for output. Used to return more than one value from a method. The calling code doesn’t need to initialize the variable, but the method must assign a value to it before it returns.
inPass by reference for input. A reference is passed for performance (avoiding a copy), but the method cannot modify the variable. The variable must be initialized before being passed.

A common use case for out is the int.TryParse method, which tries to parse a string into an integer and returns a boolean indicating success, while providing the result through an out parameter.

string userInput = "123";
// We declare 'parsedValue' right at the call site
if (int.TryParse(userInput, out int parsedValue))
{
Console.WriteLine($"Successfully parsed: {parsedValue}");
}
else
{
Console.WriteLine("Invalid number.");
}
  • Single Responsibility Principle: A method should do one thing and do it well. Avoid creating monolithic methods that handle too many tasks.
  • Clear Naming: Use descriptive, verb-based names for methods (e.g., GetUserById, CalculateTotalPrice).
  • Keep it Short: Aim for short, focused methods. If a method gets too long, consider breaking it down into smaller private helper methods or local functions.
  • Use Expression Bodies for Simplicity: If a method is a one-liner, an expression-bodied member (=>) can improve readability.