关于return:在C#中使用’out’关键字返回多个值

Returning Multiple Value with the 'out' Keyword in C#

我目前正在努力理解它的含义,当它说"out"关键字,我们能够返回多个值。例如,来自msdn站点(https://msdn.microsoft.com/en-us/library/ee332485.aspx):"…下面的示例使用out返回三个变量和一个方法调用。"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class OutReturnExample
{
    static void Method(out int i, out string s1, out string s2)
    {
        i = 44;
        s1 ="I've been returned";
        s2 = null;
    }
    static void Main()
    {
        int value;
        string str1, str2;
        Method(out value, out str1, out str2);
        // value is now 44
        // str1 is now"I've been returned"
        // str2 is (still) null;
    }
}

我不确定我是否只是没有正确地阅读描述,但似乎method()根本不返回(不使用'return'关键字)任何内容,并且基本上分配字段(类似地通过传递ref)。这与其他源一致,它们声明使用"out"可以返回多个值。我是否误解了返回词的上下文,或者是我没有正确理解这个概念?


方法确实没有返回您正确注意到的值。refout都使用参考文献。

ref会让编译器知道,变量在进入函数之前应该已经初始化了(当您在该函数之前使用该变量并希望现在更改某些内容时,这很有用)。out会让编译器知道对象是在它调用的函数内部初始化的。所以ref是双向的,out是唯一的。

所以,是的,它实际上并不返回什么。但另一方面,它会将值赋给变量,通过这些变量,调用方法也会得到新的值。本质上,你可以把这看作是回报。

简而言之:

  • EDCOX1的0个参数-这些与C++引用具有相同的功能参数,以及

  • out参数-这些参数允许从方法中返回数据,但不允许进入方法。

我也建议你读一下这个答案和乔恩·斯基特的博客中关于参数传递的内容。它会给你很多关于这个概念的信息。如乔恩·斯基特所说,使用refout时要小心:

It's basically a way of getting another return value, and should
usually be avoided precisely because it means the method's probably
trying to do too much.


你说得对,这个方法最多只能返回一件事(从你所说的意义上来说)。或者,根据您的声明(返回类型为void),当方法完成时,它根本不会向调用代码返回任何内容。

如果要从方法中获取多个值,可以使用以下几个选项:

  • 返回classstruct—这是一回事,但它可以包含多个值(该事物的属性)。

  • 根据您的示例,使用out修饰符将一些参数传递到方法中。outref相似,因为您的方法处理的是实际值,而不是它的副本。但与ref不同,该方法必须在方法完成之前将值赋给标记为out的任何参数(如果没有,则会得到编译器错误)。您可以有多个参数,上面有一个out修饰符。

  • 所以这有点取决于你所说的回报。在返回值的意义上,您的示例代码不返回任何内容(它是用返回类型void声明的),如果您将其更改为返回类型,它最多可以返回一个内容作为返回值。但是,从告诉调用代码方法中所做的操作的意义上讲,然后使用out参数,您可以对多个值这样做。


    它使用术语return表示其语义含义,而不是将其用作关键字。

    从语义上讲,当您使用out关键字时,您指定了两件事:

  • 参数不用于输入。
  • 参数的值将在方法返回之前被明确指定。
  • 在这方面,out参数是从该方法返回的值。

    编译器确实执行了这些语义。以下代码将生成几个警告:

    1
    2
    3
    4
    public static void Test(out int x)
    {
        Console.WriteLine(x);
    }

    Error CS0177 The out parameter 'x' must be assigned to before control leaves the current method

    Error CS0269 Use of unassigned out parameter 'x'

    请注意,C 7(即Visual Studio 2017)允许您在方法调用中声明变量。

    鉴于:

    1
    2
    3
    4
    5
    public static void  Test(out int x, out int y)
    {
        x = 1;
        y = 2;
    }

    C 7允许您这样做:

    1
    2
    Test(out int x, out int y);
    Console.WriteLine($"x = {x}, y = {y}");

    由于变量在同一语句中声明和初始化,因此这种语法使"返回"更为明显。

    同样,在C 7中,可以使用元组而不是out,我认为它更好(而且在lambdas中效果更好!).

    上述示例可在C 7中改写如下:

    1
    2
    3
    4
    5
    6
    public static (int x, int y)  Test()
    {
        int x = 1;
        int y = 2;
        return (x, y);
    }

    然后你可以这样做:

    1
    2
    (int x, int y) = Test();
    Console.WriteLine($"x = {x}, y = {y}");