Fluent Building for Func and Profit
1 min readAug 28, 2022
functional patterns in C#
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);