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

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


当前回答

在c# 7及以上版本中,可以看到这个答案。

在以前的版本中,你可以使用。net 4.0+的元组:

例如:

public Tuple<int, int> GetMultipleValue()
{
     return Tuple.Create(1,2);
}

有两个值的元组有Item1和Item2作为属性。

其他回答

有几种方法可以做到这一点。你可以使用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;
}

现在c# 7已经发布了,您可以使用新包含的元组语法

(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}.");

您还可以为元素提供名称(因此它们不是“Item1”、“Item2”等)。你可以通过在签名或返回方法中添加一个名字来实现:

(string first, string middle, string last) LookupName(long id) // tuple elements have names

or

return (first: first, middle: middle, last: last); // named tuple elements in a literal

它们也可以被解构,这是一个非常好的新功能:

(string first, string middle, string last) = LookupName(id1); // deconstructing declaration

查看这个链接,看看更多的例子可以做什么:)

作为一种替代方法,您可以将方法设置为void并且不返回任何内容。相反,创建一个带有参数的公共类,并在方法中设置它们。

public class FooBar()
{
    public string foo { get; set; }
    public int bar { get; set; }
}

然后试试这个方法

public void MyMethod(Foo foo, Bar bar)
{
    FooBar fooBar = new FooBar();
    fooBar.foo = "some string";
    fooBar.bar = 1;
}