using System.Collections;
using System.Collections.Generic;
public interface IMyQueryable<T> : IEnumerable<T>
IMyQueryable<T> Where<T>(Func<T, bool> filter);
public string Name { get; set; }
public string Surname { get; set; }
public int Age { get; set; }
public class CustomContext : IMyContextProvider
private readonly User[] _Users = new User[]
new() { Name = "John", Surname = "Doe", Age = 35 },
new(){ Name = "John", Surname = "Doe", Age = 33 },
new() { Name = "Sarah", Surname = "Connor", Age = 30 }
public MyQueryable<User> Users => new MyQueryable<User>(this);
public IEnumerable<User> UsersRaw => _Users;
public IEnumerable<T> GetRaw<T>() =>
typeof(T) == typeof(User)
: throw new ArgumentException($"Unknown type {typeof(T)}");
public interface IMyContextProvider
IEnumerable<T> GetRaw<T>();
public static void Main(string[] args)
var ctx = new CustomContext();
.Where<User>(e => e.Name == "John");
.Where<User>(e => e.Surname == "Doe")
Console.WriteLine(string.Join(", ", ages));
Console.WriteLine(new[] { 35, 33 }.SequenceEqual(ages));
.Where<User>(e => e.Age > 0)
Console.WriteLine(string.Join(", ", names));
Console.WriteLine(new[] { "John", "John" }.SequenceEqual(names));
public class MyQueryable<T> : IMyQueryable<T>
private readonly IMyContextProvider _Context;
public MyQueryable(IMyContextProvider context)
IEnumerator<T> IEnumerable<T>.GetEnumerator()
IEnumerator<T> Cast<T>(IEnumerator iterator)
while (iterator.MoveNext())
yield return (T)iterator.Current;
return Cast<T>(GetEnumerator());
internal List<Func<T, bool>> Filters = new List<Func<T, bool>>();
public IMyQueryable<T> Where<T>(Func<T, bool> filter)
clone.Filters.Add(filter);
public IEnumerator GetEnumerator()
IEnumerable<T> Filter(IEnumerable<T> source, Func<T, bool> filter)
foreach (var value in source)
var source = _Context.GetRaw<T>();
foreach (var filter in Filters)
source = Filter(source, filter);
foreach (var value in source)
public MyQueryable<T> Clone<T>()
var result = new MyQueryable<T>(_Context)
Filters = new List<Func<T, bool>>()
foreach (var filter in Filters)
result.Filters.Add(filter as Func<T, bool>);