我试图在我正在处理的包装上提供一个不错的API,并且我遇到了以下问题:
这是我的沙箱代码:
public interface ISomeInterface
{
Task<int> SomeMethod(int i);
Task<Task<int>> SomeOtherMethod(int i);
}
public class TestClass<TSource>
{
public TWrap ReturnExpressionAsIs<TWrap>(Expression<Func<TSource, TWrap>> expression)
{
return default(TWrap);
}
public TImplicit SomeExpressionFromTask<TWrap, TImplicit>(Expression<Func<TSource, TWrap>> expression) where TWrap : Task<TImplicit>
{
return default(TImplicit);
}
}
我正在使用这样的代码:
var testProxy = new TestClass<ISomeInterface>();
// Task<int> - working as intended
var ordinaryTypeInfer = testProxy.ReturnExpressionAsIs(d => d.SomeMethod(5));
// int - working as intended
var expressionExplicit = testProxy.SomeExpressionFromTask<Task<int>, int>(d => d.SomeMethod(5));
// compiler error - shouldn't this be possible through type inference?
var expressionImplicitAttempt = testProxy.SomeExpressionFromTask(d => d.SomeMethod(5));
基本上我期待TImplicit是SomeMethod的int,也可以是SomeOtherMethod的任务(但是如果可选的那个对我来说是不可能的话)。
答案 0 :(得分:1)
不,不是真的。
但是,你过度复杂了。而不是TWrap: Task<TImplicit>
,只需直接使用Task
:
public TImplicit SomeExpressionFromTask<TSource, TImplicit>
(Expression<Func<TSource, Task<TImplicit>>> expression)
{
return default(TImplicit);
}
如果您无法简化泛型类型参数和约束,那么为类型推断添加伪参数可能是有意义的:
public V DoStuff<T, U, V>(Func<T, U> func, V dummy) where U: A<V> { ... }
允许您致电
DoStuff(i => SomeFun(i), default(int));
当然,这实际上只是一种辅助方法 - 在核心实现中这样做是没有意义的。