Skip to content

Instantly share code, notes, and snippets.

@philiplaureano
Created July 29, 2014 03:14
Show Gist options
  • Save philiplaureano/6bcc6e81fd00b49e4aae to your computer and use it in GitHub Desktop.
Save philiplaureano/6bcc6e81fd00b49e4aae to your computer and use it in GitHub Desktop.
An example of how to implement partially-applied generic factories with Functify so that you can create functions that create generic type factory methods with only some of the type parameters left open
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FunctifyBench
{
using Functify;
using LinFu.Delegates;
public class SampleGenericType<T1, T2>
{
public void DoSomething(T1 first, T2 second)
{
Console.WriteLine(first);
Console.WriteLine(second);
}
}
public static class ArrayFunctorInputExtensions
{
public static Func<TResult> Narrow<T1, TResult>(this Func<T1[], TResult> builderFunc, T1 arg1)
{
return () => builderFunc(new[] { arg1 });
}
public static Func<TResult> Narrow<T1, TResult>(this Func<T1[], TResult> builderFunc, T1 arg1, T1 arg2)
{
return () => builderFunc(new[] { arg1, arg2 });
}
public static Func<TResult> Narrow<T1, TResult>(this Func<T1[], TResult> builderFunc, T1 arg1, T1 arg2, T1 arg3)
{
return () => builderFunc(new[] { arg1, arg2, arg3 });
}
public static Func<TResult> Narrow<T1, TResult>(this Func<T1[], TResult> builderFunc, T1 arg1, T1 arg2, T1 arg3, T1 arg4)
{
return () => builderFunc(new[] { arg1, arg2, arg3, arg4 });
}
public static Func<TResult> Narrow<T1, TResult>(this Func<T1[], TResult> builderFunc, T1 arg1, T1 arg2, T1 arg3, T1 arg4, T1 arg5)
{
return () => builderFunc(new[] { arg1, arg2, arg3, arg4, arg5 });
}
public static Func<TResult> Narrow<T1, TResult>(this Func<T1[], TResult> builderFunc, T1 arg1, T1 arg2, T1 arg3, T1 arg4, T1 arg5, T1 arg6)
{
return () => builderFunc(new[] { arg1, arg2, arg3, arg4, arg5, arg6 });
}
public static Func<TResult> Narrow<T1, TResult>(this Func<T1[], TResult> builderFunc, T1 arg1, T1 arg2, T1 arg3, T1 arg4, T1 arg5, T1 arg6, T1 arg7)
{
return () => builderFunc(new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 });
}
public static Func<TResult> Narrow<T1, TResult>(this Func<T1[], TResult> builderFunc, T1 arg1, T1 arg2, T1 arg3, T1 arg4, T1 arg5, T1 arg6, T1 arg7, T1 arg8)
{
return () => builderFunc(new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 });
}
public static Func<TResult> Narrow<T1, TResult>(this Func<T1[], TResult> builderFunc, T1 arg1, T1 arg2, T1 arg3, T1 arg4, T1 arg5, T1 arg6, T1 arg7, T1 arg8, T1 arg9)
{
return () => builderFunc(new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 });
}
public static Func<TResult> Narrow<T1, TResult>(this Func<T1[], TResult> builderFunc, T1 arg1, T1 arg2, T1 arg3, T1 arg4, T1 arg5, T1 arg6, T1 arg7, T1 arg8, T1 arg9, T1 arg10)
{
return () => builderFunc(new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 });
}
public static Func<TResult> Narrow<T1, TResult>(this Func<T1[], TResult> builderFunc, T1 arg1, T1 arg2, T1 arg3, T1 arg4, T1 arg5, T1 arg6, T1 arg7, T1 arg8, T1 arg9, T1 arg10, T1 arg11)
{
return () => builderFunc(new[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11 });
}
}
class Program
{
static void Main(string[] args)
{
var typeDefinition = typeof(SampleGenericType<,>);
Func<Type[], Type> makeGenericType = typeDefinition.MakeGenericType;
Func<Type, Type, Type> createType = (type1, type2) => makeGenericType.Narrow(type1, type2)();
// This is equivalent to creating a
// SampleGenericType<T1,T2> with T1 being an open param, and T2 = typeof(int)
var createPartial = createType.Partial<Func<Type, Type>>(Args.Open, typeof(int));
// Create a SampleGenericType<string, int> type
var firstType = createPartial(typeof(string));
// Create a SampleGenericType<double, int> type
var secondType = createPartial(typeof(double));
return;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment