Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type inference for fluent API

I have the following extension methods:

public static IFoo Foo(this IFluentApi api, Action action);

public static IFoo<TResult> Foo<TResult>(
    this IFluentApi api, Func<TResult> func);

public static IBar Bar(this IFoo foo);

public static void FooBar(this IBar bar, Action action);

public static void FooBar<TResult>( // <- this one cannot work as desired 
    this IBar bar, Action<TResult> action);

The generic interfaces are always derived from their corresponding non-generic interface.

Unfortunately, to make this work:

api.Foo(x => ReturnLong())
   .Bar()
   .FooBar(x => ...); // x should be of type long

I need to also implement the following extension method:

public static IBar<TResult> Bar<TResult> (this IFoo<TResult> foo);

and change the last of the above extension methods to:

public static void FooBar<TResult>(
    this IBar<TResult> bar, Action<TResult> action);

As I actually not only have Bar() between Foo() and FooBar() but a VERY long chain of methods I would have huge additional implementation costs.

Is there any way to avoid this problem and "magically" forward the TResult generic parameter?

Edit:

Without losing type inference!

like image 792
D.R. Avatar asked Jul 24 '13 18:07

D.R.


1 Answers

Assuming you're able to go from an IFoo<TResult> to an IFoo and your chain of methods does not care about TResult you may be able to save some of the implementing by changing the usage to something like:

api.Foo(x => ReturnLong())
   .Bars(foo=>foo.Bar1() //where foo is an IFoo
                 .Bar2()
                 .Bar3()
                 ...
    )
   .FooBar(x => ...);
like image 161
SLuck49 Avatar answered Oct 18 '22 17:10

SLuck49