Last active
November 19, 2017 10:27
-
-
Save mharasimowicz/a4ff68ab4b890d8b866dcdbd6795cc3b to your computer and use it in GitHub Desktop.
Piping operator example
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
using System; | |
using System.Linq.Expressions; | |
namespace FuncPipeExample | |
{ | |
class PipeableFunc<TResult> | |
{ | |
internal readonly Func<TResult> _funcInstance; | |
public PipeableFunc(Func<TResult> funcInstance) => | |
_funcInstance = funcInstance ?? throw new ArgumentNullException(nameof(funcInstance)); | |
public static explicit operator PipeableFunc<TResult>(TResult result) => | |
new PipeableFunc<TResult>(() => result); // explicit conversion | |
public static explicit operator PipeableFunc<TResult>(Func<TResult> funcInstance) => | |
new PipeableFunc<TResult>(funcInstance); // explicit conversion | |
public static implicit operator Func<TResult>(PipeableFunc<TResult> pipeableFunc) => | |
pipeableFunc._funcInstance; // implicit conversion | |
public static implicit operator TResult(PipeableFunc<TResult> pipeableFunc) => | |
pipeableFunc._funcInstance(); // implicit conversion | |
} | |
class PipeableFunc<TArg, TResult> | |
{ | |
internal readonly Func<TArg, TResult> _funcInstance; | |
public PipeableFunc(Func<TArg, TResult> funcInstance) => | |
_funcInstance = funcInstance ?? throw new ArgumentNullException(nameof(funcInstance)); | |
public static explicit operator PipeableFunc<TArg, TResult>(Func<TArg, TResult> funcInstance) => | |
new PipeableFunc<TArg, TResult>(funcInstance); // explicit conversion | |
public static implicit operator Func<TArg, TResult>(PipeableFunc<TArg, TResult> pipeableFunc) => | |
pipeableFunc._funcInstance; // implicit conversion | |
public static PipeableFunc<TResult> operator |(TArg a, PipeableFunc<TArg, TResult> b) => | |
new PipeableFunc<TResult>(() => b._funcInstance(a)); | |
public static PipeableFunc<TResult> operator |(Func<TArg> a, PipeableFunc<TArg, TResult> b) => | |
new PipeableFunc<TResult>(() => b._funcInstance(a())); | |
public static PipeableFunc<TResult> operator |(PipeableFunc<TArg> a, PipeableFunc<TArg, TResult> b) => | |
new PipeableFunc<TResult>(() => b._funcInstance(a._funcInstance())); | |
} | |
class PipeableAction | |
{ | |
internal readonly Action _actionInstance; | |
public PipeableAction(Action actionInstance) => | |
_actionInstance = actionInstance ?? throw new ArgumentNullException(nameof(actionInstance)); | |
public static explicit operator PipeableAction(Action actionInstance) => | |
new PipeableAction(actionInstance); // explicit conversion | |
public static explicit operator PipeableAction(Expression<Action> actionInstance) => | |
new PipeableAction(actionInstance.Compile()); // explicit conversion | |
public static implicit operator Action(PipeableAction pipeableAction) => | |
pipeableAction._actionInstance; // implicit conversion | |
public static PipeableAction operator |(PipeableAction pipeableAction1, PipeableAction pipeableAction2) => | |
new PipeableAction(() => { pipeableAction1._actionInstance(); pipeableAction2._actionInstance(); }); | |
} | |
class PipeableAction<TArg> | |
{ | |
internal readonly Action<TArg> _actionInstance; | |
public PipeableAction(Action<TArg> actionInstance) => | |
_actionInstance = actionInstance ?? throw new ArgumentNullException(nameof(actionInstance)); | |
public static explicit operator PipeableAction<TArg>(Action<TArg> actionInstance) => | |
new PipeableAction<TArg>(actionInstance); // explicit conversion | |
public static explicit operator PipeableAction<TArg>(Expression<Action<TArg>> actionInstance) => | |
new PipeableAction<TArg>(actionInstance.Compile()); // explicit conversion | |
public static implicit operator Action<TArg>(PipeableAction<TArg> pipeableAction) => | |
pipeableAction._actionInstance; // implicit conversion | |
public static implicit operator Action(PipeableAction<TArg> pipeableAction) => | |
new Action(() => pipeableAction._actionInstance(default(TArg))); // implicit conversion | |
public static implicit operator PipeableAction(PipeableAction<TArg> pipeableAction) => | |
new PipeableAction(() => pipeableAction._actionInstance(default(TArg))); // implicit conversion | |
public static PipeableAction<TArg> operator |(Func<TArg, TArg> a, PipeableAction<TArg> b) => | |
new PipeableAction<TArg>(arg => b._actionInstance(a(arg))); | |
public static PipeableAction<TArg> operator |(TArg a, PipeableAction<TArg> b) => | |
new PipeableAction<TArg>(arg => b._actionInstance(a)); | |
} | |
class PipeableAction<TArg, TArg2> | |
{ | |
internal readonly Action<TArg, TArg2> _actionInstance; | |
public PipeableAction(Action<TArg, TArg2> actionInstance) => | |
_actionInstance = actionInstance ?? throw new ArgumentNullException(nameof(actionInstance)); | |
public static explicit operator PipeableAction<TArg, TArg2>(Action<TArg, TArg2> actionInstance) => | |
new PipeableAction<TArg, TArg2>(actionInstance); // explicit conversion | |
public static explicit operator PipeableAction<TArg, TArg2>(Expression<Action<TArg, TArg2>> actionInstance) => | |
new PipeableAction<TArg, TArg2>(actionInstance.Compile()); // explicit conversion | |
public static implicit operator Action<TArg, TArg2>(PipeableAction<TArg, TArg2> pipeableAction) => | |
pipeableAction._actionInstance; // implicit conversion | |
} | |
class Program | |
{ | |
static readonly PipeableAction<string> writeLine = | |
new PipeableAction<string>(text => Console.WriteLine(text)); | |
static readonly PipeableAction readKey = | |
new PipeableAction(() => Console.ReadKey()); | |
static readonly PipeableFunc<string, string[]> doubleSay = | |
new PipeableFunc<string, string[]>(str => new string[] { str, str }); | |
static readonly PipeableFunc<string[], string> capitalize = | |
new PipeableFunc<string[], string>(str => str[0].ToString().ToUpperInvariant() + str[1]); | |
static readonly PipeableFunc<string, string> exclaim = | |
new PipeableFunc<string, string>(str => str + '!'); | |
static readonly PipeableFunc<string[], string> getFirst = | |
new PipeableFunc<string[], string>(args => args != null && args.Length > 0 | |
? args[0] | |
: null); | |
static readonly PipeableFunc<string, string> makeNonWhitespace = | |
new PipeableFunc<string, string>(str => !string.IsNullOrWhiteSpace(str) | |
? str | |
: "hello"); | |
static void Main(string[] args) | |
{ | |
Action result = args | |
| getFirst | |
| makeNonWhitespace | |
| doubleSay | |
| capitalize | |
| exclaim | |
| writeLine | |
| readKey; | |
result(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment