0Pricing
C# Academy · Lesson

Composability tips

Keep LINQ composable: use small pure predicates/transforms, compose delegates, add tiny extension helpers, and return IEnumerable pipelines.

Composability tips is a free C# Academy lesson on CoddyKit — lesson 3 of 3. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, one of 3 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Composable LINQ overview

Goal: Make LINQ easy to grow.

  • Write small pure predicates/transforms
  • Compose functions (no side effects)
  • Add tiny extension helpers
  • Return IEnumerable<T> pipelines

Pure helpers reused

Extract tiny pure methods and pass them as method groups. Reuse keeps pipelines short and readable.

using System;
using System.Linq;

public class Program
{
  static bool IsEven(int n) { return n % 2 == 0; }   // pure predicate
  static int Square(int n) { return n * n; }         // pure transform

  public static void Main(string[] args)
  {
    int[] xs = new int[] { 1, 2, 3, 4, 5, 6 };

    var q = xs
      .Where(IsEven)     // reuse predicate
      .Select(Square);   // reuse transform

    foreach (int v in q) Console.WriteLine(v); // 4 16 36
  }
}

Composing predicates

Build new predicates by composing smaller ones. This keeps logic testable and reusable.

using System;
using System.Linq;

public class Program
{
  // Return a predicate n > threshold
  static Func<int, bool> GreaterThan(int threshold)
  {
    return delegate(int n) { return n > threshold; };
  }

  // Combine two predicates with AND
  static Func<int, bool> And(Func<int, bool> a, Func<int, bool> b)
  {
    return delegate(int n) { return a(n) && b(n); };
  }

  static bool IsEven(int n) { return n % 2 == 0; }

  public static void Main(string[] args)
  {
    int[] xs = new int[] { 1, 2, 3, 4, 5, 6 };

    Func<int, bool> gt2 = GreaterThan(2);
    Func<int, bool> evenAndGt2 = And(IsEven, gt2);

    var q = xs.Where(evenAndGt2); // even and > 2 => 4,6

    foreach (int v in q) Console.WriteLine(v);
  }
}

Readable extensions

Add a small extension to express intent (e.g., WhereNot). Keep it simple and side-effect free.

using System;
using System.Collections.Generic;
using System.Linq;

public static class LinqEx
{
  public static IEnumerable<T> WhereNot<T>(this IEnumerable<T> src, Func<T, bool> predicate)
  {
    foreach (T item in src)
    {
      if (!predicate(item)) yield return item;
    }
  }
}

public class Program
{
  static bool IsVowel(char c)
  {
    char x = Char.ToLower(c);
    return x == 'a' || x == 'e' || x == 'i' || x == 'o' || x == 'u';
  }

  public static void Main(string[] args)
  {
    char[] letters = new char[] { 'a', 'b', 'c', 'e', 'i' };

    var consonants = letters.WhereNot(IsVowel);

    foreach (char c in consonants) Console.WriteLine(c); // b, c
  }
}

Reusable pipeline helpers

Expose reusable IEnumerable<T> helpers. Callers can keep composing (OrderBy, Take, etc.).

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
  static bool IsEven(int n) { return n % 2 == 0; }
  static int Square(int n) { return n * n; }

  // Reusable pipeline helper: filter evens and square
  public static IEnumerable<int> SquaresOfEvens(IEnumerable<int> xs)
  {
    foreach (int x in xs)
    {
      if (IsEven(x)) yield return Square(x);
    }
  }

  public static void Main(string[] args)
  {
    int[] data = new int[] { 1, 2, 3, 4, 5, 6 };

    var pipeline = SquaresOfEvens(data); // composable
    var topTwo = pipeline.OrderByDescending(x => x).Take(2);

    foreach (int v in topTwo) Console.WriteLine(v); // 36, 16
  }
}

Composability checklist

Tips:

  • Prefer pure helpers; avoid side effects inside Select/Where.
  • Compose predicates and transforms; name them well.
  • Return IEnumerable<T> from helpers so callers can extend the chain.
  • Materialize late; avoid ToList in the middle unless needed.

Best practice for composability

Quick check: What practice best keeps LINQ pipelines composable and testable?

Recap

Recap: Extract small pure helpers, compose predicates, add tiny extensions, and return pipelines so callers can keep chaining.

Frequently asked questions

Is the “Composability tips” lesson free?

Yes — the full text of “Composability tips” is free to read here on the web, and the C# Academy course includes 3 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO.

What will I learn in “Composability tips”?

Keep LINQ composable: use small pure predicates/transforms, compose delegates, add tiny extension helpers, and return IEnumerable pipelines. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C# Academy?

No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 3, so you can start here or from the beginning and move at your own pace.

How long does the “Composability tips” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C# Academy lesson?

Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. GroupBy, Join, Aggregate, projections (anonymous types)
  2. Materialization (ToList, ToDictionary) & perf notes
  3. Composability tips
← Back to C# Academy