是否可以将任务类型推断为泛型类型,而无需在表达式中指定它?

时间:2016-04-01 10:46:21

标签: c# expression

我试图在我正在处理的包装上提供一个不错的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的任务(但是如果可选的那个对我来说是不可能的话)。

1 个答案:

答案 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));

当然,这实际上只是一种辅助方法 - 在核心实现中这样做是没有意义的。