将泛型方法转换为异步导致泛型参数的问题

glo*_*ter 4 .net c# generics task-parallel-library async-await

在一个名为的静态类中StaticHelper,我有以下泛型static方法:

public static class StaticHelper
{
    public static TResponse GenericMethod<TResponse, TRequest>(TRequest request,
                                                           Func<TRequest, TResponse> method)
    where TRequest  : BaseRequest
    where TResponse : BaseResponse, new()
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

Func<TRequest, TResponse> method是被调用的方法的名称GenericMethod.GenericMethod用作WCF方法的包装器来记录请求/响应等:

public override SomeCustomResponse Request(SomeCustomRequest request)
{
    // GenericMethod above called here
    return StaticHelper.GenericMethod(request, ExecuteRequest));
}

private SomeCustomResponse ExecuteRequest(SomeCustomRequest request)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

我现在正试图创建它的async等价物:

public static async Task<TResponse> GenericMethodAsync<TResponse, TRequest>(TRequest request,
                                                           Func<TRequest, TResponse> method)
    where TRequest  : BaseRequest
    where TResponse : BaseResponse, new()
{
    // ...
}

// i have removed the override keyword here as I don't need it
public async Task<SomeCustomResponse> Request(SomeCustomRequest request)
{
    // GenericMethodAsync above called here
    return await StaticHelper.GenericMethodAsync(request, ExecuteRequest));
}

private async Task<SomeCustomResponse> ExecuteRequest(SomeCustomRequest request)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这最终导致两个错误:

public async Task<SomeCustomResponse> Request(SomeCustomRequest request)(第二个异步方法):

1)该类型Task<SomeCustomResponse>不能用作TResponse泛型类型或方法中的类型参数' StaticHelper.GenericMethodAsync<TResponse, TRequest>(TRequest, Func<TRequest, TResponse>)'.没有隐式引用转换从Task<SomeCustomResponse>BaseResponse

...和:

2)Task<SomeCustomResponse>必须是具有公共无参数构造函数的非抽象类型,以便TResponse在泛型类型或方法中将其用作参数' 'StaticHelper.GenericMethodAsync<TResponse, TRequest>(TRequest, Func<TRequest, TResponse>)

更新:以下René的回答使错误消失.我现在有一个新的:

无法隐式将类型' Task<TResponse>' 转换为' TResponse'

违规行StaticHelper.GenericMethodAsync试图执行Func:

var response = method(request); // <-- Cannot implicitly convert type 'Task<TResponse>' to 'TResponse'
Run Code Online (Sandbox Code Playgroud)

......显然,解决方案就是await:

var response = await method(request);
Run Code Online (Sandbox Code Playgroud)

Ren*_*ogt 6

您需要更改声明GenericMethodAsync,因为method(ExecuteRequest)的返回类型现在Task<TResponse>而不是TResponse:

public static async Task<TResponse> GenericMethodAsync<TResponse, TRequest>(
                     TRequest request,
                     Func<TRequest, Task<TResponse>> method) // <-- change here
                            where TRequest  : BaseRequest
                            where TResponse : BaseResponse, new()
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

并考虑重新命名ExecuteRequestExecuteRequestAsync了.

当然,你现在必须相应改变method内部的使用GenericMethodAsync:

var response = await method(request);
Run Code Online (Sandbox Code Playgroud)