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. This is 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, and your progress syncs across the web and the CoddyKit app. The C# Academy course includes 3 lessons in total.
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
Recap
Recap: Extract small pure helpers, compose predicates, add tiny extensions, and return pipelines so callers can keep chaining.
Learn C# with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 93
- Lessons
- 346
Frequently Asked Questions
Is the “Composability tips” lesson free?
Yes — the full text of “Composability tips” is free to read here on the web. 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. The C# Academy course includes 3 lessons in total.
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, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 3.
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
- GroupBy, Join, Aggregate, projections (anonymous types)
- Materialization (ToList, ToDictionary) & perf notes
- Composability tips