DEV Community

Renan Martins
Renan Martins

Posted on

Teaching My Team How to Build LINQ from Scratch

After weeks exploring IEnumerable, yield return, and xUnit, we’ve reached the final step of our journey: building our own LINQ methods.

This is the story of how I used this project to teach my team C# fundamentals and remove the illusion that LINQ is “something magical.”

It’s not magic, it’s just beautifully structured C# code.


Why I Built This Project for My Team

As a team lead, I noticed some developers using LINQ daily without really knowing how it worked.

So, I decided to create a simple project to teach them how to implement LINQ-like methods from scratch.

We used everything we learned throughout this series:

  • IEnumerable<T> and iteration
  • Extension methods
  • yield return and deferred execution
  • Unit testing with xUnit

The complete project is available on GitHub:

👉 github.com/reenanms/My.Linq


Using the Test Project from the Previous Article

In the last article, we wrote tests for Where and Any.

Now it’s time to make those tests pass with your own implamentation!

We’ll create a new C# project called MyLinq and add a class LinqExtensions with empty methods.

public static class LinqExtensions
{
    public static IEnumerable<T> Where<T>(this IEnumerable<T> list, Func<T, bool> filter)
    {
        throw new NotImplementedException();
    }

    public static bool Any<T>(this IEnumerable<T> list)
    {
        throw new NotImplementedException();
    }

    public static bool Any<T>(this IEnumerable<T> list, Func<T, bool> filter)
    {
        throw new NotImplementedException();
    }
}
Enter fullscreen mode Exit fullscreen mode

Then, we’ll update our test project to reference this one.

Finally, replace this line in the tests:

using System.Linq;
Enter fullscreen mode Exit fullscreen mode

with:

using MyLinq;
Enter fullscreen mode Exit fullscreen mode

Now your tests will target your implementation instead of the real LINQ.


Implementing .Where()

Here’s our custom version of the Where method:

public static IEnumerable<T> Where<T>(this IEnumerable<T> list, Func<T, bool> filter)
{
    foreach (var item in list)
    {
        if (filter(item))
            yield return item;
    }
}
Enter fullscreen mode Exit fullscreen mode

This method uses yield return to generate results one by one, the same concept used internally by LINQ.
Thanks to deferred execution, no new list is created in memory; items are returned as needed.
Run your tests, and the Where tests from the previous article should now pass ✅


Implementing .Any()

Now let’s implement Any.
We’ll write two versions: one without parameters, and one that takes a condition.

public static bool Any<T>(this IEnumerable<T> list)
{
    foreach (var _ in list)
        return true;
    return false;
}

public static bool Any<T>(this IEnumerable<T> list, Func<T, bool> filter)
{
    foreach (var item in list)
    {
        if (filter(item))
            return true;
    }

    return false;
}
Enter fullscreen mode Exit fullscreen mode

The first one checks if any element exists, while the second checks if any element matches a given condition.
Simple, efficient, and clear.


Running the Tests

Now, run all the tests again:

dotnet test
Enter fullscreen mode Exit fullscreen mode

If everything is set up correctly, all tests should pass 🎉

This moment is satisfying. Watching green check marks appear knowing you just rebuilt core LINQ behavior from scratch.


What The Team Learned

When we finished this project, something changed in how my team approached C#.
They realized:

  • LINQ isn’t “doing magic”, it’s just well-written extension methods.
  • IEnumerable<T> and yield return are extremely powerful tools.
  • Writing tests first helps clarify logic and prevents mistakes.

It became one of our favorite learning sessions as a team.


Wrapping Up the Series

This article closes the From Blank to LINQ Mastery series, a journey that started when I blanked in an interview question about LINQ 😅
Now, we’ve gone full circle: understanding it, rebuilding it, and teaching it.

If you haven’t seen the previous articles, you can start from the beginning here:

  1. When I Went Blank in an Interview – and What I Learned About LINQ
  2. Understanding IEnumerable in C#: The Foundation of LINQ
  3. How Extension Methods Unlock LINQ’s Magic in C#
  4. C#’s Hidden Gem: How Yield Return Makes Iterators Simple
  5. Unit Testing Our First LINQ-like Methods in C#
  6. Teaching My Team How to Build LINQ from Scratch

✅ That’s all, folks!

💬 Let’s Connect

Have any questions, suggestions for improvement, or just want to share your thoughts?

Feel free to leave a comment here, or get in touch with me directly on LinkedIn — I’d love to connect!

Top comments (0)