Last active
December 19, 2017 12:51
-
-
Save cameronpresley/1bd47ea84edad7d6052b69b71b0d2def to your computer and use it in GitHub Desktop.
Function Extensions with Examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Example | |
{ | |
public void DemonstrateMap() | |
{ | |
Func<int, string> tostring = s => s.ToString(); | |
4.Map(tostring); | |
} | |
public void DemonstrateCompose() | |
{ | |
Func<int, List<int>> toList = a => new List<int> {a}; | |
Func<List<int>, List<string>> toStringList = a => a.Select(x => x.ToString()).ToList(); | |
Func<int, List<string>> numberToStringList = toList.Compose(toStringList); | |
42.Map(numberToStringList); | |
} | |
public void DemonstrateDo() | |
{ | |
4.Map(x => x.ToString()).Do(Console.WriteLine); | |
} | |
public void DemonstrateApply() | |
{ | |
Func<int, int, int> add = (a, b) => a + b; | |
Func<int, int> add2 = add.Apply(2); | |
add2.Apply(4).Do(Console.WriteLine); | |
} | |
public void DemonstrateIdentity() | |
{ | |
Console.WriteLine(4.Map(FunctionExtensions.Identity) == 4); | |
} | |
public void DemonstrateNoOp() | |
{ | |
4.Do(FunctionExtensions.NoOp).Do(Console.WriteLine); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class FunctionExtensions | |
{ | |
public static U Map<T, U>(this T value, Func<T, U>func) | |
{ | |
return func(value); | |
} | |
public static Func<T, T2> Compose<T, T1, T2>(this Func<T, T1>first, Func<T1, T2>second) | |
{ | |
return x => second(first(x)); | |
} | |
public static T Do<T>(this T value, Action<T>action) | |
{ | |
action(value); | |
return value; | |
} | |
public static Func<T1> Apply<T, T1>(this Func<T, T1>func, T value) | |
{ | |
return () => func(value); | |
} | |
public static Func<T1, T2> Apply<T, T1, T2>(this Func<T, T1, T2> func, T value) | |
{ | |
return a => func(value, a); | |
} | |
public static Func<T1, T2, T3> Apply<T, T1, T2, T3>(this Func<T, T1, T2, T3>func, T value) | |
{ | |
return (a, b) => func(value, a, b); | |
} | |
public static Func<T1, T2, T3, T4> Apply<T, T1, T2, T3, T4>(this Func<T, T1, T2, T3, T4>func, T value) | |
{ | |
return (a, b, c) => func(value, a, b, c); | |
} | |
public static T Identity<T>(T value) | |
{ | |
return value; | |
} | |
public static void NoOp<T>(this T value) | |
{ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice!! These are pretty slick. I was playing around with it some then I discovered something interesting. While you can use local functions as arguments to methods expecting variations of delegates, i.e.;
Action
,Action<in T, ...>
,Func<out TResult>
,Func<in T, ..., out TResult>
, etc. You cannot use them as arguments into an extension method where they would be implicitly converted to the delegate.That is VERY odd. For example, this works:
I was trying to change your example usages to leverage local functions, so instead of this:
Do this (notice the use of local functions rather than
Func<int, List<int>>
andFunc<List<int>, List<string>>
):There is a compiler error.