我读了这个问题的c++版本,但并没有真正理解它。

有人能解释清楚,如果它可以在c#中完成,以及如何?


当前回答

一些答案建议使用out参数,但我建议 不使用这个,因为它们不与异步方法一起工作。看到 这是更多的信息。

其他的答案是使用Tuple,我也会推荐它,但是使用c# 7.0中引入的新特性。

(string, string, string) LookupName(long id) // tuple return type
{
    ... // retrieve first, middle and last from data storage
    return (first, middle, last); // tuple literal
}

var names = LookupName(id);
WriteLine($"found {names.Item1} {names.Item3}.");

更多信息可以在这里找到。

其他回答

你可以试试这个

public IEnumerable<string> Get()
 {
     return new string[] { "value1", "value2" };
 }

当你的方法是异步的,你想返回多个属性。你必须这样做:

public async Task<(int, int)> GetMultipleValues(){
   return (1,2);
}

有几种方法可以做到这一点。你可以使用ref参数:

int Foo(ref Bar bar) { }

这将向函数传递一个引用,从而允许函数在调用代码的堆栈中修改对象。虽然这在技术上不是一个“返回”值,但它是一种让函数做类似事情的方法。在上面的代码中,该函数将返回一个int和(可能)修改bar。

另一种类似的方法是使用out形参。out形参与ref形参相同,只是附加了编译器强制的规则。这条规则是,如果你将一个输出参数传递给一个函数,该函数需要在返回之前设置它的值。除此之外,out形参的工作原理与ref形参类似。

最后一种方法(在大多数情况下是最好的)是创建一个封装两个值的类型,并允许函数返回该类型:

class FooBar 
{
    public int i { get; set; }
    public Bar b { get; set; }
}

FooBar Foo(Bar bar) { }

最后一种方法更简单,更容易阅读和理解。

在面向对象的方式中使用一个这样的类:

class div
{
    public int remainder;

    public int quotient(int dividend, int divisor)
    {
        remainder = ...;
        return ...;
    }
}

函数成员返回大多数调用者主要感兴趣的商。此外,它将余数存储为数据成员,之后调用者可以很容易地访问它。

通过这种方式,您可以有许多额外的“返回值”,这在实现数据库或网络调用时非常有用,在这些调用中可能需要大量的错误消息,但仅在发生错误时才需要。

我也在OP提到的c++问题中输入了这个解决方案。

你可以使用动态对象。我认为它比Tuple有更好的可读性。

static void Main(string[] args){
    var obj = GetMultipleValues();
    Console.WriteLine(obj.Id);
    Console.WriteLine(obj.Name);
}

private static dynamic GetMultipleValues() {
    dynamic temp = new System.Dynamic.ExpandoObject();
    temp.Id = 123;
    temp.Name = "Lorem Ipsum";
    return temp;
}