为什么c#不允许多个返回值?

本文关键字:返回值 不允许 为什么 | 更新日期: 2023-09-27 18:04:05

我只是想知道…为什么c#不允许多个返回值?

目前,我们通过返回一个类或使用out来表达我们返回多个值的意图,如下所示。

static void Check(MyTask task )
{
    if (GoodReasonsNotTo(task))
    {
        throw new ApplicationException("There are good reasons not to do this.");
    }
}
public static int UglyDo( MyTask task, out string response )
{
    Check(task);
    //...
    response = "Done";
    return 7;
}
static void Main(string[] args)
{
    var task = new MyTask("Add multiple return values");
    string response;
    var err = UglyDo(task, out reponse));
}

上面的代码可以用不同的方式表示:

static void Check(MyTask task )
{
    if (GoodReasonsNotTo(task))
    {
        throw new ApplicationException("There are good reasons not to do this.");
    }
}
public static (int, string) PrettyDo(MyTask task)
{
    Check(task);
    //...
    return 7, "Done.";
}
static void Main(string[] args)
{
    var task = new MyTask("Add multiple return values");
    var (err, response) = PrettyDo(task); 
}

返回值和函数参数有什么特别的吗?他们看起来一样,做的事情也一样。为什么他们不平等?

而且,它能支持它的未来吗?

顺便说一句。StackOverflow的语法高亮器很好地处理了这个问题——这当然意味着这将是一件好事。

为什么c#不允许多个返回值?

你问得真有趣。刚刚宣布c# 7.0将支持 [MSDN]

问得好。实际上,目前一些高级语言(如Go)以及至少一些汇编语言(如MIPS)都支持这一点,MIPS为参数保留了几个寄存器,为返回值保留了两个寄存器(但这至少部分是惯例,而不是寄存器之间的实际物理差异)。从更一般的意义上讲,返回值没有什么特别的"特殊"。

至于为什么c#还没有直接支持这个,我在这里做了一些推测,但是c#仍然很大程度上是面向对象的开发。甚至像匿名函数这样的特性也是以面向对象的方式"在底层"实现的,所以我怀疑,如果将来它们最终做了像多个返回值这样的事情,它本质上也会成为创建和返回对象的语法糖。基本上,你现在显式地返回一个对象也许将来它会隐式地返回一个。

Edit:现在我们最接近多个返回值的可能是元组,不幸的是,它现在在c#中具有非常不方便的语法(它们在其他一些。net语言中使用要方便得多,特别是f#,我真的希望看到它获得更多的突出,但这只是我的意见,我猜)。显然,他们正在考虑在c#的未来版本中改进这一点,这可能是我们将在一段时间内得到的最接近的(我想这将与我的怀疑保持一致,即他们在多个返回值方面所做的任何事情都只是对象的语法糖)。

我仍然是c#的新手,但是像这样的解决方案不会帮助你吗?创建一个带有所需参数的新类,并创建一个返回该类的函数。

public static testClass PrettyDo(MyTask task)
{
    Check(task);
    //...
    testClass answer = new testClass();
    answer.param1 = 7;
    answer.param2 = "Done.";
    return answer;
}
public class testClass
{
    public int param1 { get; set; }
    public string param2 { get; set; }
}

如何使用Tuple:

public static Tuple<int, string> PrettyDo(MyTask task)
{
    Check(task);
    //...
    return Tuple.Create(7, "Done.");
}
static void Main(string[] args)
{
    var task = new MyTask("Add multiple return values");
    var result = PrettyDo(task); 
    var err = result.Item1;
    var response = result.Item2;
}

它不像一些高级语言那样支持解包,但它非常接近你所需要的。