In C#, we can use Func<>
and Action<>
types to store what are essentially managed pointers to methods. However, in my experience, they need to be explicitly typed when defined: Func<int> someFunc = myObject.MyMethod;
I am trying to design a fluent API that can chain various methods assuming they have a compatible signature. For instance:
public int IntMethodA( value ) { return value * 2; }
public int IntMethodB( value ) { return value * 4; }
public double DoubleMethod( value ) { return value / 0.5; }
public double ChainMethod( value )
{
return IntMethodA( value )
.Then( IntMethodB )
.Then( DoubleMethod );
}
This is something that is supported by .NET's Task<>
class. However, for learning purposes, I am trying to develop something like this from scratch, and it has left me with a few questions:
IntMethodA
returns an int. In order to achieve something like this, I would likely need to write an extension method forFunc<>
, along with all of its possible generic overloads. This means I'll need to cast the initial method as aFunc
and then return a builder object that can accept subsequent methods. Is there any way I can avoid that initial cast, so as to maintain complete fluency?Is there a way to automate or make generic the builder methods that accept functions and add them to the chain?
For instance, consider:
public int IntMultiply( int a, int b ) { return a * b; }
public Tuple<double, double> Factor( int value )
{
/* Some code that finds a set of two numbers that multiply to equal 'value' */
}
These two methods have different signatures and return types. However, if I want to chain IntMultiply().Then( Factor );
it should work, because the input of Factor
is the same type as the output of IntMultiply
.
However, creating a generic fluent API that can do this seems like a challenge. I would need to be able to somehow take the return type of IntMultiply
and constrain any additional methods to accept only that type as the input. Is this even possible to do?
If anyone has insights as to how this project can be approached, or if there are existing projects that do something similar, I would appreciate it.