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

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


当前回答

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

class div
{
    public int remainder;

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

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

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

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

其他回答

作为一种替代方法,您可以将方法设置为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;
}

一些答案建议使用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}.");

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

有许多方法;但如果你不想创建一个新的对象或结构或类似的东西,你可以在c# 7.0之后这样做:

 (string firstName, string lastName) GetName(string myParameter)
    {
        var firstName = myParameter;
        var lastName = myParameter + " something";
        return (firstName, lastName);
    }

    void DoSomethingWithNames()
    {
        var (firstName, lastName) = GetName("myname");

    }

你可以试试这个

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

在c# 7中有一个新的元组语法:

static (string foo, int bar) GetTuple()
{
    return ("hello", 5);
}

你可以返回一个记录:

var result = GetTuple();
var foo = result.foo
// foo == "hello"

你也可以使用新的解构器语法:

(string foo) = GetTuple();
// foo == "hello"

但是要小心序列化,所有这些都是语法糖——在实际编译的代码中,这将是一个Tuple<string, int>(根据接受的答案),包含Item1和Item2,而不是foo和bar。这意味着序列化(或反序列化)将使用这些属性名。

因此,对于序列化,声明一个记录类并返回它。

c# 7中的另一个新特性是改进了out形参的语法。你现在可以内联声明out,这在某些情况下更适合:

if(int.TryParse("123", out int result)) {
    // Do something with result
}

但是,大多数情况下,您将在. net自己的库中使用它,而不是在您自己的函数中。