【发布时间】:2013-07-24 18:55:36
【问题描述】:
我有以下扩展方法:
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);
泛型接口总是派生自它们对应的非泛型接口。
不幸的是,要完成这项工作:
api.Foo(x => ReturnLong())
.Bar()
.FooBar(x => ...); // x should be of type long
我还需要实现以下扩展方法:
public static IBar<TResult> Bar<TResult> (this IFoo<TResult> foo);
并将上述扩展方法中的最后一个更改为:
public static void FooBar<TResult>(
this IBar<TResult> bar, Action<TResult> action);
因为我实际上不仅在Foo() 和FooBar() 之间有Bar(),而且还有一个非常长的方法链,我将有巨大的额外实施成本。
有没有办法避免这个问题并“神奇地”转发TResult 泛型参数?
编辑:
不会丢失类型推断!
【问题讨论】:
-
您的 fluent API 中是否有任何理由使用非泛型方法?如果没有,请完全抛弃它们,转而使用通用的。
-
你为什么没有
public static IBar<T> Bar (this IFoo<T> foo);? -
@Chris:不幸的是,我应该在 Foo(Action) 中返回什么?
-
@supercat:用户不需要,为什么要实现呢?不幸的是,如果我想使用类型推断,我必须实现它......现在的问题是:如何克服这个缺陷?
-
我根本不会称之为“缺陷”。我认为您最好的选择是要么实现所有方法,要么创建一个包装通用构建器,其中
TResult在类级别定义一次。 (我想这样做意味着放弃扩展方法的使用,并且仍然需要你实现这些方法)我说只是咬紧牙关,做正确的事情并避免“魔术”。编辑:对不起,我想我现在完全理解这个问题了。您需要在非通用调用之间链接通用信息。是的,尝试制作一个单独的构建器类。
标签: c# generics fluent fluent-interface