我读了这个问题的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}.");

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

其他回答

一些答案建议使用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#中这样做。你能做的就是有一个out形参或者返回你自己的类(或者结构,如果你想让它是不可变的)。

Using out parameter
public int GetDay(DateTime date, out string name)
{
  // ...
}
Using custom class (or struct)
public DayOfWeek GetDay(DateTime date)
{
  // ...
}

public class DayOfWeek
{
  public int Day { get; set; }
  public string Name { get; set; }
}

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

class div
{
    public int remainder;

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

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

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

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

c#的未来版本将包括命名元组。 看看channel9的演示 https://channel9.msdn.com/Events/Build/2016/B889

跳到13:00讲元组的内容。这将允许如下内容:

(int sum, int count) Tally(IEnumerable<int> list)
{
// calculate stuff here
return (0,0)
}

int resultsum = Tally(numbers).sum

(视频中不完整的例子)

之前的帖子是对的。c#方法不能返回多个值。然而,你确实有几个选择:

返回一个包含多个成员的结构 返回类的实例 使用输出参数(使用out或ref关键字) 使用字典或键值对作为输出

这里的利与弊通常很难弄清楚。如果您返回一个结构,请确保它很小,因为结构是值类型并传递给堆栈。如果你返回一个类的实例,这里有一些设计模式,你可能想要使用,以避免引起问题-类的成员可以修改,因为c#通过引用传递对象(你不像在VB中那样有ByVal)。

最后,您可以使用输出参数,但我将限制在只有两个(如3个或更少)参数的情况下使用此方法-否则事情将变得丑陋且难以维护。此外,输出参数的使用可能会抑制灵活性,因为每次需要向返回值中添加内容时都必须更改方法签名,而返回结构或类实例时无需修改方法签名即可添加成员。

从架构的角度来看,我建议不要使用键值对或字典。我发现这种编码风格需要使用方法的代码中的“秘密知识”。它必须提前知道键将是什么,值的含义是什么,如果开发人员在内部实现中改变了字典或KVP的创建方式,那么很容易在整个应用程序中创建故障级联。