您要求的内容实际上是discriminated union。 C#本质上并不是真的有这样的东西。有几种方法可以解决这个问题。首先,考虑一下我所说的尝试输入/输出模式:
public bool GetAllResults(string token, string username, out List<AllReportVM> results);
这是正常的比较简单的方法,但它实际上并没有给你错误消息(至少给它通常执行的方式)和out
参数不适用于async
方法。所以我们可以排除这一点。
第二个选项是throw an exception上的错误,这就是我想在90%的情况下,推荐:
public async Task<List<AllReportVM>> GetAllReports(string token, string username)
{
var httpClient = GetHttpClient();
if (CrossConnectivity.Current.IsConnected) {
var response = await httpClient.GetAsync ("getdashboardreports.ashx").ConfigureAwait (false);
if (response.IsSuccessStatusCode) {
var content = response.Content;
string jsonString = await content.ReadAsStringAsync().ConfigureAwait (false);
return JsonConvert.DeserializeObject<List<AllReportVM>> (jsonString);
} else {
throw new RequestException("SystemError");
}
} else {
throw new RequestException("Internet Connectivity Error");
}
}
,并呼吁这一点,你不得不使用:
try
{
var list = await obj.GetAllReports(token, username);
...
}
catch (RequestException ex)
{
Console.WriteLine(ex.Message);
}
这是一个非常稳固,完善的模式。事实上,您可能应该已经对可能在应用程序中发生的各种其他异常使用异常处理。但是,它确实有一些性能影响,您应该避免为简单控制流程使用异常。对于需要提出大量请求并希望有效处理失败的应用程序(例如批处理),这可能不是一种选择。当我遇到在过去这样的情况下,我找到了实现自定义类是有用的,例如:
public class RequestResult<T>
{
public bool Success { get; }
public T Result { get; }
public string ErrorMessage { get; }
private RequestResult(bool success, T result, string errorMessage)
{
this.Success = success;
this.Result = result;
this.ErrorMessage = errorMessage;
}
public static RequestResult<T> Success(T result)
{
return new RequestResult<T>(true, result, null);
}
public static RequestResult<T> Failure(string errorMessage)
{
return new RequestResult<T>(false, default(T), errorMessage);
}
}
public async Task<RequestResult<List<AllReportVM>>> GetAllReports(string token, string username)
{
var httpClient = GetHttpClient();
if (CrossConnectivity.Current.IsConnected) {
var response = await httpClient.GetAsync ("getdashboardreports.ashx").ConfigureAwait (false);
if (response.IsSuccessStatusCode) {
var content = response.Content;
string jsonString = await content.ReadAsStringAsync().ConfigureAwait (false);
var result = JsonConvert.DeserializeObject<List<AllReportVM>> (jsonString);
return RequestResult.Success(result);
} else {
return RequestResult.Failure("SystemError");
}
} else {
return RequestResult.Failure("Internet Connectivity Error");
}
}
你用泛型类型尝试过吗 –
不,你不能那样做。当客户说'ServerData data = await GetAllReports();'时,编译器必须知道'ServerData'是正确的返回类型。编译器无法知道请求在运行时是成功还是失败!如果我是你,我会创建一个Response类,其中包含返回的所有信息:成功布尔值,ErrorMessage字符串,结果ServerData。如果没有错误等,只需将ErrorMessage留空即可。*编辑*或抛出异常,当然。 – Blorgbeard