C#模板和意外/意外推断

时间:2016-08-26 16:22:03

标签: c# generics

我正在使用一堆遗留的Web服务,并试图提出一种简化的方法来包装调用并检查可能返回的自定义错误类型。我认为我很接近,但C#推断出与我的意图不同的含义,我不确定我做错了什么。我希望有人可以指出我的错误:

我已经为每个遗留服务的客户端代理添加了一个简单的接口,并为调用方法和查看响应创建了一个扩展方法(每个服务都有自己的错误类型,但都归结为一个数字和一条消息)。

    public static ApiResult<TModel,TResult> Call<TService,TResult,TModel>(this TService service, Func<TService,TResult> apiCall, TModel model) 
            where TService: ILegacyService 
            where TModel: BaseModel
    {
        ApiResult<TModel, TResult> result = default(ApiResult<TModel, TResult>);

        try
        {
            TResult apiResult = apiCall(service);
            /* extract/normalize custom, non-exception error types */
            result = new ApiResult<TModel, TResult>(model, apiResult, normalizedErrors);
        }
        catch(Exception ex)
        {
            result = new ApiResult<TModel, TResult>(model, default(TResult), exception: ex);
        }
        return result;
    }

ApiResult类型如下:

public class ApiResult<TModel,TResult>
{
    public ApiResult(TModel model, TResult response, 
            NormalizedErrorCollection errorList = null, Exception exception = null) { ... }
}

我希望对特定错误进行一系列检查,就像一系列可以将人性化消息分配给BaseModel中的错误模型的catch块一样,例如

serviceInstance.Call(s => s.SomeMethod("Foo", 42), modelInstance)
    .On<ServiceCode>(ServiceCode.MaxQty, m => m.Message = "No more for you")
    .On<ServiceCode>(ServiceCode.NoID, m => m.Message = "Parent is gone")
    .On<Exception>((m,e) => m.Message = "Unexpected error")
    .Success((m,r) => m.Result = r.Result)

我的问题是在顶部,帮助方法推断出我不想要的含义:

CartService.Call(s => s.AddToCart(request.storeId, lineItem), model);

C#/ VS表示&lt;方法响应类型&gt;不能用作类型参数TModel并且&lt;之间没有转换。方法响应类型&gt;和BaseModel。

我似乎无法弄清楚为什么apiCall TResult的返回类型被推断为模型类型。任何帮助将不胜感激! (找到模板问题的具体答案同样困难,所以如果这与现有答案匹配,我会道歉,但我确实尝试先搜索)。

1 个答案:

答案 0 :(得分:1)

上述评论中的错误信息表明AddToCartResponse不是来自BaseModel