Skip to content

Instantly share code, notes, and snippets.

@mharasimowicz
Last active November 19, 2017 10:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mharasimowicz/a4ff68ab4b890d8b866dcdbd6795cc3b to your computer and use it in GitHub Desktop.
Save mharasimowicz/a4ff68ab4b890d8b866dcdbd6795cc3b to your computer and use it in GitHub Desktop.
Piping operator example
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