C# 返回多个类型

C# 返回多个类型,c#,function,c#-4.0,xamarin,C#,Function,C# 4.0,Xamarin,在我的xamarin应用程序中,我有一个从服务器获取数据的方法,如果HTTP请求成功,我需要该方法返回数据;如果服务器返回错误,则需要“系统错误”字符串;如果服务器没有连接,则需要“Internet连接错误”字符串 我想知道如何将返回类型设置为返回其中一个。我知道Tuple可以返回多个。但我相信两者都有,而不是两者都有 我的代码 public async Task<List<AllReportVM>> GetAllReports(string token, string

在我的xamarin应用程序中,我有一个从服务器获取数据的方法,如果HTTP请求成功,我需要该方法返回数据;如果服务器返回错误,则需要“系统错误”字符串;如果服务器没有连接,则需要“Internet连接错误”字符串

我想知道如何将返回类型设置为返回其中一个。我知道Tuple可以返回多个。但我相信两者都有,而不是两者都有

我的代码

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 {
                return "SystemError";
            }
        } else {
            return "Internet Connectivity Error";

        }
    }
公共异步任务GetAllReports(字符串标记、字符串用户名) { var httpClient=GetHttpClient(); if(交叉连接.当前.断开连接){ var response=await httpClient.GetAsync(“getdashboardreports.ashx”).ConfigureAwait(false); if(响应。IsSuccessStatusCode){ var content=response.content; 字符串jsonString=await content.ReadAsStringAsync().ConfigureAwait(false); 返回JsonConvert.DeserializeObject(jsonString); }否则{ 返回“SystemError”; } }否则{ 返回“Internet连接错误”; } }
如果除了成功返回之外,只有返回类型是错误,那么您应该抛出异常。如果您有一个特定的异常故事,您应该创建一个从异常类继承的类并抛出它。如果存在描述预期问题的异常,则应该选择该异常。然后调用方法可以根据需要捕获并处理它。

查看您的代码,您可能希望抛出异常,这主要是因为您返回的两个字符串似乎都表明发生了异常

还要问你自己“当这个方法返回时,我将如何处理输出?”如果你不知道类型,你当然可以做一些事情,比如If(结果是string),但是你想在代码中乱丢东西吗?仅仅处理一个异常不是更容易吗

如果您确实需要这样做,您可以返回任务,您只需要在执行此操作时检查调用者的结果类型。例如:

var result = await GetAllReports(token, username)
if (result is string)
{
     //Do Something   
}
if(result is List<AllReportVM>)
{
    //Do Something
}

public async Task<object> 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 {
            return "SystemError";
        }
    } else {
        return "Internet Connectivity Error";

    }
}
var result=await GetAllReports(令牌、用户名)
if(结果为字符串)
{
//做点什么
}
如果(结果是列表)
{
//做点什么
}
公共异步任务GetAllReports(字符串标记、字符串用户名)
{
var httpClient=GetHttpClient();
if(交叉连接.当前.断开连接){
var response=await httpClient.GetAsync(“getdashboardreports.ashx”).ConfigureAwait(false);
if(响应。IsSuccessStatusCode){
var content=response.content;
字符串jsonString=await content.ReadAsStringAsync().ConfigureAwait(false);
返回JsonConvert.DeserializeObject(jsonString);
}否则{
返回“SystemError”;
}
}否则{
返回“Internet连接错误”;
}
}

你所要求的实际上是一个。C#并不是天生就有这样的东西。有几种方法可以解决这个问题。首先,考虑一下我所说的尝试/输出模式:

public bool GetAllResults(string token, string username, out List<AllReportVM> results);
若要称之为此,您必须使用:

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");
    }
}
公共类请求结果
{
公共bool成功{get;}
公共T结果{get;}
公共字符串错误消息{get;}
private RequestResult(布尔成功、T结果、字符串错误消息)
{
成功=成功;
结果=结果;
this.ErrorMessage=ErrorMessage;
}
公共静态请求结果成功(T结果)
{
返回新的RequestResult(true、result、null);
}
公共静态请求结果失败(字符串错误消息)
{
返回新的RequestResult(false,默认值(T),errorMessage);
}
}
公共异步任务GetAllReports(字符串标记、字符串用户名)
{
var httpClient=GetHttpClient();
if(交叉连接.当前.断开连接){
var response=await httpClient.GetAsync(“getdashboardreports.ashx”).ConfigureAwait(false);
if(响应。IsSuccessStatusCode){
var content=response.content;
字符串jsonString=await content.ReadAsStringAsync().ConfigureAwait(false);
var result=JsonConvert.DeserializeObject(jsonString);
返回RequestResult.Success(result);
}否则{
返回RequestResult.Failure(“SystemError”);
}
}否则{
返回RequestResult.Failure(“Internet连接错误”);
}
}

我的第一个选择是在错误情况下抛出异常

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 Exception("SystemError");
        }
    } else {
        throw new Exception("Internet Connectivity Error");

    }
}
公共异步任务GetAllReports(字符串标记、字符串用户名) { var httpClient=GetHttpClient(); if(交叉连接.当前.断开连接){ var response=await httpClient.GetAsync(“getdashboardreports.ashx”).ConfigureAwait(false); if(响应。IsSuccessStatusCode){ var content=response.content; 字符串jsonString=await content.ReadAsStringAsync().ConfigureAwait(false); 返回JsonConvert.DeserializeObject(jsonString); }否则{ 抛出新异常(“系统错误”); } }否则{ 抛出新异常(“Internet连接错误”); } } 这将需要调用方捕获异常,但是您只需要一个返回路径

我的第二个选择是添加一个out参数
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 Exception("SystemError");
        }
    } else {
        throw new Exception("Internet Connectivity Error");

    }
}
public Task<List<AllReportVM>> GetAllReports(string token, string username, out string error)
{
    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);

            error = null;
            return JsonConvert.DeserializeObject<List<AllReportVM>> (jsonString);
        } else {
            error = "SystemError";
            return null;
        }
    } else {
        error = "Internet Connectivity Error";
        return null;
    }
}