您要求的內容實際上是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