Defunctionalized predicates

Run Settings
LanguageC#
Language Version
Run Command
using System; using System.Linq; public abstract class Predicate { public static Func<T, bool> ToFunc<T>(Predicate p) { if (p is ConstPredicate) { var p_ = p as ConstPredicate; return (x) => p_.Value; } if (p is PropertyPredicate) { var p_ = p as PropertyPredicate; var property = typeof(T).GetProperty(p_.Name); return (x) => (bool)property.GetValue(x); } if (p is AndPredicate) { var p_ = p as AndPredicate; var a = ToFunc<T>(p_.A); var b = ToFunc<T>(p_.B); return (x) => a(x) && b(x); } throw new Exception("Unsupported predicate type"); } public static string ToSQL(Predicate p) { if (p is ConstPredicate) { var p_ = p as ConstPredicate; return p_.Value ? "true" : "false"; } if (p is PropertyPredicate) { var p_ = p as PropertyPredicate; return p_.Name; } if (p is AndPredicate) { var p_ = p as AndPredicate; return "(" + ToSQL(p_.A) + ") AND (" + ToSQL(p_.B) + ")"; } throw new Exception("Unsupported predicate type"); } } public sealed class ConstPredicate : Predicate { public bool Value { get; } public ConstPredicate(bool value) { Value = value; } } public sealed class PropertyPredicate : Predicate { public string Name { get; } public PropertyPredicate(string name) { Name = name; } } public sealed class AndPredicate : Predicate { public Predicate A { get; } public Predicate B { get; } public AndPredicate(Predicate a, Predicate b) { A = a; B = b; } } public static class Program { public sealed class Person { public bool Alive { get; } public Person(bool alive) { Alive = alive; } } public static void Main() { var predicate = new AndPredicate( new ConstPredicate(true), new PropertyPredicate(nameof(Person.Alive)) ); var people = new[] { new Person(alive: true), new Person(alive: false), }; foreach (var person in people.Where(Predicate.ToFunc<Person>(predicate))) { Console.WriteLine(person.Alive); } Console.WriteLine(Predicate.ToSQL(predicate)); } }
Editor Settings
Theme
Key bindings
Full width
Lines