Data points passing through a minimal query filter
View source on GitHubB1Z0N/MyLINQ

lablanguagesdataacademic

MyLINQ

C# sequence-operator learning lab.
  • C#
  • .NET
  • LINQ
  • Extension methods
Date
March 2022
Status
Historical
Visibility
Public

LINQ of my implementation. Most of the standard sequence operators, rewritten by hand as extension methods with a My prefix — MySelect, MyAggregate, joins, zips, ordering, set operations — each one tested against the real LINQ result with NUnit.

The focus is the logic of the methods, so the deferred ones are real yield-based iterators and the eager ones throw the same exceptions the originals do:

using MyLINQ;

var numbers = new List<int> { 5, 1, 4, 2, 3 };

// deferred, yield-based — nothing runs until enumeration
var query = numbers
    .MyPrepend(0)
    .MyConcat(new[] { 6, 7 })
    .MySelect(n => n * n)
    .MySkip(2)
    .MyTake(4);

foreach (var n in query) Console.Write($"{n} ");   // 1 16 4 9

// eager operators behave like the originals, exceptions included
numbers.MyMax();                        // 5
numbers.MyAverage();                    // 3
numbers.MyAll(n => n > 0);              // true
new List<int>().MyMax();                // throws InvalidOperationException

// and the heavier ones: joins, zips, ordering, set operations
numbers.MyOrderBy(n => -n);             // 5 4 3 2 1
numbers.MyZip(numbers.MyReverse(), (a, b) => a + b);   // 8 3 8 3 8
numbers.MyUnion(new[] { 4, 5, 6 });     // 5 1 4 2 3 6

The tests run every My method beside its System.Linq counterpart over the same inputs — empty lists, single elements, repeated values — and assert the results are equal.