从方法返回多个结果

Cha*_*son 14 c# return

我尝试使用Try Catch块提高我的技能并更好地处理错误.

我有一个执行常见任务的类,在这种情况下检索Facebook AccessToken.如果成功,我想返回AccessToken字符串,如果不是,我想返回错误消息.这些都是字符串,所以没问题.但是当检查代码调用端的返回值时,如何有效地执行此操作?

这就像我需要返回2个值.在成功尝试的情况下,返回= true,"ACESSCODEACXDJGKEIDJ",或者如果失败,则返回= false,"Ooops,出现错误"+ ex.ToString();

然后检查返回值很容易(理论上).我可以想到返回一个true/false返回,然后为字符串设置一个Session变量.

什么是从方法返回多个结果的方法?

mus*_*fan 22

创建一个Result类并返回它...

public class Result
{
   public bool Success {get;set;}
   public string AccessToken {get;set;}
   public string ErrorMessage {get;set;}
}


public Result GetFacebookToken()
{
   Result result = new Result();

   try{
      result.AccessToken = "FACEBOOK TOKEN";
      result.Success = true;
   }
   catch(Exception ex){
      result.ErrorMessage = ex.Message;
      result.Success = false;
   }

   return result;
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样调用这段代码......

Result result = GetFacebookToken();

if(result.Success)
{
   //do something with result.AccessToken
}
else
{
   //do something with result.ErrorMessage 
}
Run Code Online (Sandbox Code Playgroud)


Dar*_*rov 8

我想到了两种可能性

  1. 使用TryXXX模式(在某些BCL方法中使用,例如DateTime.TryParse).
  2. 设计一个包含操作状态和结果的类,然后让您的方法返回此类.

我们先来看看TryXXX模式.它基本上是一个返回布尔值并将结果作为out参数的方法.

public bool TryXXX(string someInput, out string someResult, out string errorMessage)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

这将被消耗如下:

string someResult;
string errorMessage;
if (!TryXXX("some parameter", out someResult, out errorMessage))
{
    // an error occurred => use errorMessage to get more details
}
else
{
    // everything went fine => use the results here
}
Run Code Online (Sandbox Code Playgroud)

在第二种方法中,您只需设计一个包含所有必要信息的类:

public class MyResult
{
    public bool Success { get; set; }
    public string ErrorMessage { get; set; }

    public string SomeResult { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后让你的方法返回这个类:

public MyResult MyMethod(string someParameter)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

这将被消耗如下:

MyResult result = MyMethod("someParameter");
if (!result.Success)
{
    // an error occurred => use result.ErrorMessage to get more details
}
else
{
    // everything went fine => use the result.SomeResult here
}
Run Code Online (Sandbox Code Playgroud)

当然,结果可以是任何其他复杂对象,而不是(如本例所示)字符串.


use*_*265 7

为了建立musefan的答案,我喜欢相同的模式,但是使用通用的Result类型,所以我可以在整个代码库中使用它:

public class Result
{
    public bool Success { get; set; }
    public string ErrorMessage { get; set; }
}

public class Result<T> : Result
{
    public T Data;
}
Run Code Online (Sandbox Code Playgroud)

我之所以喜欢这个,而不是从一个以其他方式返回数据的函数中抛出异常的原因之一就是这有助于您将该函数映射到集合上,捕获错误消息中的异常详细信息,因此您不必担心异常一个项目炸毁了整个链条.这对于从平面数据文件中解析行的情况很有用,成功的行应向前移动,但任何错误都应单独处理:

public static Result<Thing> ParseThing(string line)
{
     try 
     {
          // Parse a Thing (or return a parsing error.)
          return new Result<Thing> { Data = thing, Success = true };
     }
     catch (Exception ex)
     {
          return new Result<Thing> { Data = null, Success = false, ErrorMessage = "..." };
     }
}

...

var results = lines.Select(ParseThing);

foreach (var result in results)
{
    // Check result.Success and deal with successes/failures here.
}
Run Code Online (Sandbox Code Playgroud)

当然,你仍然可以选择在真正特殊的情况下抛出该函数的异常,因为你可以根据需要炸毁整个处理链.

PS每天都是我希望C#有多个返回值的日子.


小智 5

尝试一个元组?

public Tuple<bool, string> ReturnsBoolAndString() {
    return Tuple.Create(false, "string");
}
Run Code Online (Sandbox Code Playgroud)