我在a project I'm working on中实现了一个命令模式。这几乎是目前的结构:
public class Response
{
public bool Success { get; private set; }
public static Response CreateErrorResponse()
{
return new Response { Success = false };
}
}
public interface ICommand<T> where T : Response
{
Task<T> ExecuteAsync();
}
public abstract CommandBase : ICommand<T> where T: Response
{
protected abstract Uri BuildUrl();
protected abstract Task<T> HandleResponseAsync();
public async override Task<T> ExecuteAsync()
{
var url = BuildUrl();
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(url);
return await HandleResponseAsync(response);
}
}
我想处理HttpClient可能引发的任何异常,所以我想将CommandBase.ExecuteAsync更改为这样的......
public async override Task<T> ExecuteAsync()
{
var url = BuildUrl();
var httpClient = new HttpClient();
try
{
var response = await httpClient.GetAsync(url);
return await HandleResponseAsync(response);
}
catch (HttpRequestException hex)
{
return Response.CreateErrorResponse(); // doesn't compile
}
}
我得到的编译错误是“无法将类型响应转换为异步返回类型T”。我无法使用T.CreateErrorResponse()
,如in this question所述。
我该如何解决这个问题?
编辑给downvoters:无论你是否同意在这样的图书馆中捕捉例外,问题仍然存在!
答案 0 :(得分:3)
虽然我不确定这是最好的解决方案(或在您的特定用例中可行),但您可以做的是:
public class Response
{
public bool Success { get; private set; }
public ExceptionDispatchInfo ErrorInfo { get; private set; }
public bool HasFailed
{
get { return !Success; }
}
public static T CreateErrorResponse<T>(ExceptionDispatchInfo errorInfo) where T : Response, new()
{
var response = new T();
response.Success = false;
response.ErrorInfo = errorInfo;
return response;
}
}
用法:
catch (HttpRequestException hex)
{
return Response.CreateErrorResponse<T>(ExceptionDispatchInfo.Capture(hex)); // should compile (I did not check)
}
答案 1 :(得分:0)
您可以将响应转换为T. 编辑:添加完整源代码
public class Response
{
public bool Success { get; private set; }
public static Response CreateErrorResponse()
{
return new Response { Success = false };
}
}
public interface ICommand<T> where T : Response
{
Task<T> ExecuteAsync();
}
public abstract class CommandBase<T> : ICommand<T> where T: Response
{
protected abstract Uri BuildUrl();
protected abstract Task<T> HandleResponseAsync();
public async Task<T> ExecuteAsync()
{
var url = BuildUrl();
var httpClient = new System.Net.Http.HttpClient();
try
{
var response = await httpClient.GetAsync(url);
return null;// await HandleResponseAsync(response);
}
catch (Exception hex)
{
return (T)Response.CreateErrorResponse(); // doesn't compile
}
}
}
public async override Task<T> ExecuteAsync()
{
var url = BuildUrl();
var httpClient = new HttpClient();
try
{
var response = await httpClient.GetAsync(url);
return await HandleResponseAsync(response);
}
catch (HttpRequestException hex)
{
return (T)Response.CreateErrorResponse(); // compiles on liqpad
}
}