Methods
As programs grow, you will notice the same few lines appearing again and again: calculate GST, check a PIN code, print a bill line. A method gives a block of code a name so you can run it whenever you need it, with different inputs each time. Methods make code shorter, easier to test and much easier to read.
In this lesson you will write methods that take parameters and return values, learn the difference between local functions and class methods, and use overloading, optional arguments, ref and out, params, tuples and recursion.
Your first methods
A method has a return type, a name, a list of parameters in brackets, and a body. void means "returns nothing". In a file with top-level statements, you can write methods at the bottom of the file; they are called local functions.
Greet("Isha");
Greet("Rohan");
int area = Square(12);
Console.WriteLine($"Area: {area} sq ft");
Console.WriteLine(IsValidPin("124001"));
Console.WriteLine(IsValidPin("12400"));
void Greet(string name)
{
Console.WriteLine($"Good morning, {name}!");
}
int Square(int side) => side * side;
bool IsValidPin(string pin)
{
if (pin.Length != 6)
{
return false;
}
return pin.All(char.IsDigit);
}Good morning, Isha! Good morning, Rohan! Area: 144 sq ft True False
nameandsideare parameters: variables that receive the values you pass."Isha"and12are the arguments.returnsends a value back and ends the method immediately.int Square(int side) => side * side;is an expression-bodied method: a one-line method written with=>.- A method name says what it does, in PascalCase:
IsValidPin,CalculateFare. Methods returningbooloften start withIs,HasorCan.
Methods in a class: overloading, optional and named arguments
Most methods in real programs live inside classes. A static method belongs to the class itself, so you call it as ClassName.Method(...). Inside a class, several methods can share a name if their parameter lists differ. This is called overloading.
Console.WriteLine(Billing.Total(499));
Console.WriteLine(Billing.Total(499, 2));
Console.WriteLine(Billing.Total(1299, 1, delivery: 0));
Console.WriteLine(Billing.Total(1299.50m, 2));
static class Billing
{
public static int Total(int price, int qty = 1, int delivery = 40)
=> price * qty + delivery;
public static decimal Total(decimal price, int qty)
=> price * qty + 40;
}539 1038 1299 2639.00
qty = 1anddelivery = 40are optional parameters with default values; callers may leave them out.delivery: 0is a named argument. It makes the call readable and lets you skip optional parameters in the middle.- The compiler picks the overload that best matches the argument types:
1299.50mis adecimal, so the secondTotalruns.
Local functions cannot be overloaded; overloading is a feature of class methods.
Passing values in and getting several values out
By default, arguments are passed by value: the method gets a copy of the variable's value. For value types such as int, changing the parameter does not affect the caller. The ref keyword passes the variable itself, and out lets a method hand back an extra result. Often, a tuple is the cleanest way to return several values.
int marks = 38;
AddGrace(ref marks, 5);
Console.WriteLine($"After grace: {marks}");
bool ok = TryDivide(10, 0, out int result);
Console.WriteLine($"Division worked: {ok}, result: {result}");
(int min, int max, double avg) = Stats([66, 91, 78, 54]);
Console.WriteLine($"Min {min}, max {max}, average {avg}");
void AddGrace(ref int value, int grace)
{
value += grace;
}
bool TryDivide(int a, int b, out int quotient)
{
if (b == 0)
{
quotient = 0;
return false;
}
quotient = a / b;
return true;
}
(int Min, int Max, double Average) Stats(int[] values)
{
return (values.Min(), values.Max(), values.Average());
}After grace: 43 Division worked: False, result: 0 Min 54, max 91, average 72.25
refmust be written both in the method and at the call:AddGrace(ref marks, 5). The method can read and change the caller's variable.- An
outparameter must be assigned before the method returns. You have already used this pattern withint.TryParse. - The tuple return type
(int Min, int Max, double Average)groups three values, and(int min, int max, double avg) = ...deconstructs them into three variables.
Use ref and out sparingly. A tuple or a small record (see Records, Structs & Enums) usually makes code clearer.
params: any number of arguments
A params parameter collects any number of arguments into one collection, which is how Console.WriteLine and string.Join accept many values.
Console.WriteLine(SumAll(1, 2, 3));
Console.WriteLine(SumAll());
Console.WriteLine(SumAll(500, 250, 125, 125));
int SumAll(params int[] numbers)
{
int total = 0;
foreach (int n in numbers)
{
total += n;
}
return total;
}6 0 1000
Recursion
A recursive method calls itself. Every recursive method needs a base case that stops the calls, and each call must move closer to it.
Console.WriteLine(Factorial(5));
Console.WriteLine(DigitSum(124001));
long Factorial(int n) => n <= 1 ? 1 : n * Factorial(n - 1);
int DigitSum(int n) => n < 10 ? n : n % 10 + DigitSum(n / 10);120 8
Factorial(5) becomes 5 * Factorial(4), then 5 * 4 * Factorial(3), and so on until Factorial(1) returns 1. DigitSum adds the last digit to the digit sum of the rest: 1 + 0 + 0 + 4 + 2 + 1 = 8. Without a base case, the calls never end and the program crashes with a stack overflow. For most everyday problems a loop is simpler; recursion shines with tree-shaped data such as folders inside folders.
Common mistakes
- Not returning on every path. If one branch has no
return, you getCS0161: not all code paths return a value. - Ignoring the return value.
Square(5);on its own computes 25 and throws it away. Store or print it. - Expecting a change without
ref. Assigning to anintparameter does not change the caller's variable. - Overloading local functions. Two local functions with the same name in one scope is an error; put overloads in a class.
- Methods that do too much. If a method needs a long comment to explain it, split it into smaller methods with clear names.
Key points
- A method has a return type, name, parameters and body;
voidreturns nothing. - Top-level programs can have local functions; class methods are declared
staticor as instance methods. - Overloads share a name but differ in parameters; optional parameters and named arguments make calls flexible.
- Arguments are passed by value;
refpasses the variable itself andoutreturns extra values. - Tuples return several values neatly;
paramsaccepts any number of arguments. - Recursive methods need a base case.
Exercise
Write three methods for a Jaipur hotel. RoomCharge(int nights, int ratePerNight = 2500) returns the total room charge. Gst(int amount) returns 12% GST for amounts up to Rs 7,500 and 18% above that, as a decimal. Bill(string guest, int nights) prints a line with the guest's name, room charge, GST and total. Call Bill for Kabir (2 nights) and Meera (4 nights). (GST rates are simplified for practice.)
Show solution
Bill("Kabir", 2);
Bill("Meera", 4);
int RoomCharge(int nights, int ratePerNight = 2500) => nights * ratePerNight;
decimal Gst(int amount)
{
decimal rate = amount <= 7500 ? 0.12m : 0.18m;
return amount * rate;
}
void Bill(string guest, int nights)
{
int room = RoomCharge(nights);
decimal gst = Gst(room);
Console.WriteLine($"{guest}: room Rs {room}, GST Rs {gst}, total Rs {room + gst}");
}Kabir: room Rs 5000, GST Rs 600.00, total Rs 5600.00 Meera: room Rs 10000, GST Rs 1800.00, total Rs 11800.00
RoomCharge uses its default rate because Bill passes only nights. Multiplying an int by a decimal rate gives a decimal with two decimal places, which is why the GST prints as 600.00.
Quick Quiz
1. What does void mean in a method declaration?
void is the return type for methods that return nothing.
2. Given int Add(int a, int b = 10) => a + b;, what is Add(5)?
b is optional with default 10, so the result is 5 + 10.
3. Which keyword lets a method change the caller's int variable?
ref passes the variable itself, so the method's changes are visible to the caller.
4. What does every recursive method need?
Without a base case the method calls itself forever and the stack overflows.
Learn C# with a mentor
Free lessons get you started. Our Programming & Software Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
