Skip to Content
Course content

235: Recursive Patterns

Click on the "Edit" button in the top corner of the screen to edit your slide content.

A few years ago, I was mentoring a developer who was tasked with building a category navigation menu for a large e-commerce site. The categories were nested—Electronics had "Computers," which had "Laptops," which had "Gaming Laptops." He started by writing a foreach loop to get the top-level categories. Then he added another foreach inside that for the sub-categories. Then a third. By the time he hit the fourth level of nesting, his code was indented so far to the right that he was scrolling horizontally just to read a single line. He was exhausted, and the code was a nightmare to maintain.

The problem was that he was trying to solve a recursive problem with iterative tools. When you don't know how deep your data goes, loops are your enemy. This is where recursive patterns come in. In C#, recursion is simply a method that calls itself to solve a smaller version of the same problem until it reaches a point where it can stop.

Thinking in Trees

Most of the time, you'll use recursion when dealing with "tree" structures. Think of file directories, organizational charts, or the nested category example I mentioned. Instead of trying to predict the depth of the tree, you write a method that handles one single "node" and then tells itself to do the exact same thing for any children that node might have.

Take a look at this pattern. Imagine we have a simple Category class:

public class Category
{
    public string Name { get; set; }
    public List<Category> SubCategories { get; set; } = new List<Category>();
}

If we want to print every category in the system, regardless of how deep they are, we don't use nested loops. We use a recursive method like this:

public void PrintCategoryTree(Category category, int indentLevel = 0)
{
    // Print the current category with some indentation for visual clarity
    Console.WriteLine(new string(' ', indentLevel * 2) + category.Name);

    // The recursive step: call the same method for every sub-category
    foreach (var sub in category.SubCategories)
    {
        PrintCategoryTree(sub, indentLevel + 1);
    }
}

I love this approach because the logic is incredibly lean. The method doesn't care if the tree is two levels deep or two thousand. It just handles the current item and delegates the rest of the work back to itself.

The Guardrail: The Base Case

Here is where things can go wrong. If you've ever had a program freeze and then crash with a StackOverflowException, you've experienced a recursive function without a proper "base case." Every recursive method needs a condition that tells it when to stop calling itself. If it doesn't, it will keep adding frames to the call stack until the memory allocated for that stack is completely exhausted.

In the PrintCategoryTree example above, the base case is implicit: the foreach loop. If a category has no sub-categories, the loop doesn't execute, the method returns, and the recursion "unwinds."

However, when working with more complex recursion—like searching for a specific file in a directory—you need to be more explicit. You might check if a folder is empty or if you've reached a maximum depth limit to prevent the program from diving into a symbolic link loop that goes on forever. I always tell my team: before you write a single line of recursive code, identify exactly what the "exit" condition is. If you can't define the stop point, don't start the recursion.




📋 Practical Task

Build a Recursive Folder Size Calculator

Your task is to create a program that calculates the total size of a directory, including all its sub-directories and files. This is a classic recursive problem because you never know how many folders are nested within folders.

Requirements:

  • Create a method long GetDirectorySize(string path).
  • Inside the method, use Directory.GetFiles(path) to sum the size of all files in the current directory (you can use new FileInfo(file).Length to get the size in bytes).
  • Use Directory.GetDirectories(path) to get all sub-folders.
  • For each sub-folder found, call GetDirectorySize recursively and add its result to your total.
  • Ensure your code handles the case where a directory might be empty (your base case).

Test Case: Create a folder on your machine with a few nested folders and files of varying sizes. Run your calculator and verify that the total matches the properties window of the root folder in Windows Explorer or macOS Finder.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.