C# Recursion
Write a method named down that takes one int named n. If n is 0 or less, stop with a bare return;. Otherwise write n, then call down(n - 1) from inside the same method. From Main call down(3);. The screen should show three lines: 3, then 2, then 1. The method keeps calling itself with a smaller number until the stop ends the chain. That self-call with a stop is what this page teaches. Keep the public class named Pine.
A method that calls itself
On the scope page, mark ran once and finished. Here down runs, then starts another down with a new argument before the first call is fully done. Each call has its own n. The chain only ends when a call hits the stop.
Open the Pine file. The class name stays Pine. This page does not rename the type. Delete any mark demo leftover if that shape is still all you have in Main. Delete any paint leftover. Delete any ReadLine line. The file you keep has no wait for typing.
Outside Main, still inside the class braces, write static void down(int n). Keep void on this page: each step writes, and nothing needs to come back through a typed return value. The stop uses return; with no value — that only ends this call. Save the file before you run. The full first program is in the next box.
The file you keep
This is the version you run first. Main holds one call. down holds the stop, the writing line, and the self-call.
using System;
public class Pine
{
public static void Main()
{
down(3);
}
static void down(int n)
{
if (n <= 0)
{
return;
}
Console.WriteLine(n);
down(n - 1);
}
}
Read it from the top. using System; prepares short names. public class Pine names the type. public static void Main() is where the runtime starts. The call down(3) enters with n equal to 3. That is greater than 0, so the method writes 3, then calls down(2). That second call writes 2, then calls down(1). That third call writes 1, then calls down(0). The call with 0 hits n <= 0 and returns without writing. The chain ends. Three lines on the screen: 3, then 2, then 1.
Run it with dotnet run. The program writes three lines and stops. It does not wait for you to type. If dotnet run waits, ReadLine is still in the file. Delete that line and keep down(3); plus the down method above. The screen shows 3, then 2, then 1. If the screen shows only 4, a leftover mark(4) call is still running. If the screen shows the letters down, a writing line has quotes: Console.WriteLine("down");. You do not reinstall the .NET SDK for a screen that shows the wrong lines.
Walk one full run in order. C# starts at Main. The call down(3) enters with n equal to 3. That is greater than 0, so the method writes 3, then calls down(2). That second call writes 2, then calls down(1). That third call writes 1, then calls down(0). The call with 0 hits n <= 0 and returns without writing. The chain ends. The screen keeps the three written lines.
Each of those calls is a separate pass through the same method text. The first pass still has work waiting after it starts down(2) — namely finishing after the inner call returns. You do not write four different method names. You write one method and let the smaller argument carry the progress toward the stop.
If you change the start to down(2);, the screen should show 2 then 1. The method body stays the same; only the first argument changes, so the chain is shorter. Starting at down(4); should show four lines: 4, 3, 2, 1. Again the body is unchanged; only Main picks the first value.
Put the stop first
The stop must be checked before the writing line and before the self-call. If you write first and never test n, or if you always call down(n) with the same value, the program does not finish. Keep the if (n <= 0) block at the top of the method on this beginner shape.
using System;
public class Pine
{
public static void Main()
{
down(2);
}
static void down(int n)
{
if (n <= 0)
{
return;
}
Console.WriteLine(n);
down(n - 1);
}
}
This is the second file. It teaches the same body with a shorter start. Run dotnet run. The screen shows 2 then 1. The stop still ends the chain when n reaches 0. Writing down(n) instead of down(n - 1) sends the same number again and again. Then the program may run until the system stops it. The smaller argument is part of the idea: each call must move toward the stop.
Think of the stop as the exit door. The writing line is the work you do on this step. The self-call is the next step. If the door is missing, every step opens another step with no end. If the next step uses the same n, you never walk toward the door. Both mistakes look different in the source, but both refuse to finish cleanly on this beginner shape. After you have seen 2 then 1, put the kept down(3) file back if that is the shape you want to save.
Call chain beside the screen
Read one starter call beside the lines it produces. Each row is one visit to down that still writes.
📊 down call chain for down(3)
| Call | Value of n | Screen line |
|---|---|---|
first down(3) |
3 |
3 |
then down(2) |
2 |
2 |
then down(1) |
1 |
1 |
then down(0) |
0 |
(no line — stop) |
A common mix-up is leaving out the stop. Then every call writes and calls again forever. Another mix-up is writing after the recursive call instead of before it. On this page the writing line comes first, so the screen counts down. If you move Console.WriteLine below down(n - 1), the order of lines changes — keep the writing line above the self-call for the countdown shown here.
Scope from the previous page still matters in a small way: each call’s n is that call’s own parameter. The outer call’s n does not rewrite itself when the inner call runs. The inner call has a separate n. When the inner call returns, the outer call continues from the line after the self-call — and on this page that is simply the end of the method.
A leftover mark demo can sit in the same file and confuse the screen if Main still calls mark. Clear Main down to down(3); or down(2); while you learn this page. Do not nest down inside Main’s braces. Methods sit inside the class, next to Main.
Writing Console.WriteLine("down"); in Main writes the word down. It does not start the chain. Keep down(3); when you want the three countdown lines.
One more shape: stop writes nothing
You already saw that the call with 0 returns quietly. You can also practice a start value of 1. The screen should show a single line: 1. Then the next call is down(0), which stops.
using System;
public class Pine
{
public static void Main()
{
down(1);
}
static void down(int n)
{
if (n <= 0)
{
return;
}
Console.WriteLine(n);
down(n - 1);
}
}
This is the third file. Run dotnet run. The screen shows one line: 1. The same method body covers down(3), down(2), and down(1). Only the first argument in Main changes. That is enough for this beginner page. Deeper ideas like returning a sum from recursion wait for later courses; here the goal is the self-call, the smaller argument, and the stop.
If the screen shows nothing at all, check whether Main still calls something else, or whether the stop test is wrong — for example if (n >= 0) would stop before any write when you start with a positive n. Keep n <= 0 as the quiet exit, and keep a positive starter in Main so at least one line can appear.
You can write down(int n), stop when n is 0 or less, write n, then call down(n - 1). From Main, one call starts the whole chain. The screen shows the countdown lines. A method that never moves toward the stop does not finish. The next page is classes, where you begin building types with fields beyond these static method pages.
The screen holds the countdown
The file you keep writes 3, then 2, then 1, when Main calls down(3);. The self-call is inside down, and the letters down are not on the screen as a printed label unless you quoted them. Nesting down inside Main is not the shape this lesson builds.
🧠 Test Your Knowledge
Test Your Knowledge
Challenge yourself with this interactive quiz and see how well you understand the topic
📝 Instructions
- Read each question carefully
- Select the best answer for each question
- You can retake the quiz as many times as you want
- Your progress will be shown at the top