Fluent Building for Func and Profit

Dimitris Papadimitriou
1 min readAug 28, 2022

--

functional patterns in C#

Source

In this short article we are going to see some minimal case of the specification pattern but also is a glimpse on compositionality of C# delegates. Lets say we have this simple item

public record struct Item(int Id, string Name);List<Item> items = new List<Item> { 
new Item(1, "a"),
new Item(2, "b")
};

by creating the following extension on strings

static Func<Item, bool> AsName(this string @name) =>
item => item.Name == @name;
public static Func<Item, bool> AsId(this int @id) =>
item => item.Id == @id;

we can write the declarative

var filtered1 = items.Where("a".AsName());

by further adding the extension

static Func<T, bool> And<T>(
this Func<T, bool> @filter1,
Func<T, bool> filter2) =>
item => @filter1(item) && filter2(item);

we can write now expressions like the following;

var filtered1 = items.Where("a".AsName().And(1.AsId()));

Currying the expression

by currying the Add<> above we get the following

var filtered2 = items.Where("a".AsName().And()(1.AsId()));

but can you write something like this for example:

var filtered2 = items.Where("a".AsName().And(1).AsId()));

yes you can by some creativity on types by extension methods:

Func<Item, bool> AsId(this (Func<Item, bool>, int) @this) => 
@this.Item1.And(@this.Item2.AsId());
(Func<Item, bool>, int) And(this Func<Item, bool> @this, int x) =>
(@this, x);

Source

--

--