using System.Collections.Generic;
public interface IOperator<T, U> where T : IComparable<U>
public class EqualityOperator<T, U> : IOperator<T, U> where T : IComparable<U>
public bool Compare(T a, U b) {
return a.CompareTo(b) == 0;
public interface IFilter<T, T2> where T : List<T2> {
public abstract class ConjunctionFilter<T, T2> : IFilter<T, T2> where T : List<T2> {
public enum ConjunctionType {
public ConjunctionType Conjunction {get; set;}
public abstract T Filter(T input);
public class SingleFilter<T, T1, T2, T3> : ConjunctionFilter<T, T1> where T2 : IComparable<T3> where T : List<T1> {
public IOperator<T2, T3> storedOperator;
public override T Filter(T input) {
List<T1> output = new List<T1>();
public class MultiFilter<T, T1> : ConjunctionFilter<T, T1> where T : List<T1> {
List<ConjunctionFilter<T, T1>> subFilters = new List<ConjunctionFilter<T, T1>>();
public override T Filter(T input) {
List<T1> clonedList = new List<T1>();
clonedList.AddRange(input);
foreach (var filter in subFilters) {
clonedList = filter.Filter((T)clonedList);
List<T1> output = new List<T1>();
public struct DataEntry {
public static void Main()
MultiFilter<List<DataEntry>, DataEntry> rootFilter;