在 C# 中使用 'out' 关键字返回多个值
Returning Multiple Value with the 'out' Keyword in C#
我目前正在努力理解使用 'out' 关键字我们能够 return[=24] 的含义=] 多个值。例如来自msdn站点(https://msdn.microsoft.com/en-us/library/ee332485.aspx):“...以下示例使用了return三个具有单个方法调用的变量。”
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(不使用 'return' 关键字)任何东西完全分配字段(类似于通过 ref 传递)。这与其他来源一致,他们指出使用 'out' 可以 return 多个值。我是不是误解了 return 这个词的上下文,还是我没有正确理解这个概念?
该方法确实没有 return 您正确注意到的值。 ref
和 out
都使用引用。
ref
将让编译器知道变量在进入函数之前应该已经初始化(这在您在该函数之前使用该变量并且现在想更改某些内容时很有用)。 out
将让编译器知道该对象已在其调用的函数内初始化。所以 ref
是双向的,out
是唯一的。
所以,是的,它实际上并没有 return 东西。但另一方面,它会为您的变量赋值,您的调用方法也会通过这些变量以新值结束。从本质上讲,您可以将其视为 return.
简而言之:
ref
参数 - 这些具有与 C++ 参考相同的功能
参数,以及
out
参数 - 这些允许从方法传回数据,但不允许
进入方法。
我还建议您阅读 Jon Skeet 关于参数传递的 this SO answer and the corresponding blog。它会给你很多关于这个概念的信息。正如 Jon Skeet 所说,使用 ref
和 out
:
时要小心
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.
它使用术语 return
是为了它的语义,而不是将其用作关键字。
从语义上讲,当您使用 out
关键字时,您指定了两件事:
- 该参数未用于输入。
- 参数的值肯定会在方法前赋值returns。
在这方面,out
参数是从方法返回的值。
编译器确实强制执行这些语义。以下代码将生成几个警告:
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)将允许您在方法调用中声明变量。
给定:
public static void Test(out int x, out int y)
{
x = 1;
y = 2;
}
C# 7 允许您这样做:
Test(out int x, out int y);
Console.WriteLine($"x = {x}, y = {y}");
由于变量是在同一条语句中声明和初始化的,因此这种语法使某些东西变得更加明显"returned"。
同样在 C# 7 中,您可以使用元组代替 out
,我认为后者更好(并且与 lambda 一起工作得更好!)。
上面的例子在C#7中可以重写如下:
public static (int x, int y) Test()
{
int x = 1;
int y = 2;
return (x, y);
}
那么你可以这样做:
(int x, int y) = Test();
Console.WriteLine($"x = {x}, y = {y}");
你说得对,这个方法最多只能return(你所说的)一件事。或者,根据您的声明(return 类型 void
),当方法完成时,它不会 return 任何调用代码。
如果您想从您的方法中获取多个值,您有两种选择:
Return一个class
或struct
——那是一回事,但它可以包含多个值(那个东西的属性)
根据您的示例,使用 out
修饰符将一些参数传递到方法中。 out
与 ref
相似,因为您的方法处理的是实际值而不是它的副本。但与 ref
不同的是,该方法必须在方法完成之前为任何标记为 out
的参数赋值(如果不这样做,您将收到编译器错误)。您可以有多个带有 out
修饰符的参数。
所以这有点取决于你所说的 return 的意思。在 return 值的意义上,您的示例代码 return 什么都没有(它是用 return 类型 void
声明的),如果您将其更改为具有 return 最多可以输入 return 一件事作为它的 return 值。但是在告诉调用代码在方法中做了什么的意义上,然后使用 out
参数你可以为多个值做到这一点。
我目前正在努力理解使用 'out' 关键字我们能够 return[=24] 的含义=] 多个值。例如来自msdn站点(https://msdn.microsoft.com/en-us/library/ee332485.aspx):“...以下示例使用了return三个具有单个方法调用的变量。”
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(不使用 'return' 关键字)任何东西完全分配字段(类似于通过 ref 传递)。这与其他来源一致,他们指出使用 'out' 可以 return 多个值。我是不是误解了 return 这个词的上下文,还是我没有正确理解这个概念?
该方法确实没有 return 您正确注意到的值。 ref
和 out
都使用引用。
ref
将让编译器知道变量在进入函数之前应该已经初始化(这在您在该函数之前使用该变量并且现在想更改某些内容时很有用)。 out
将让编译器知道该对象已在其调用的函数内初始化。所以 ref
是双向的,out
是唯一的。
所以,是的,它实际上并没有 return 东西。但另一方面,它会为您的变量赋值,您的调用方法也会通过这些变量以新值结束。从本质上讲,您可以将其视为 return.
简而言之:
ref
参数 - 这些具有与 C++ 参考相同的功能 参数,以及out
参数 - 这些允许从方法传回数据,但不允许 进入方法。
我还建议您阅读 Jon Skeet 关于参数传递的 this SO answer and the corresponding blog。它会给你很多关于这个概念的信息。正如 Jon Skeet 所说,使用 ref
和 out
:
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.
它使用术语 return
是为了它的语义,而不是将其用作关键字。
从语义上讲,当您使用 out
关键字时,您指定了两件事:
- 该参数未用于输入。
- 参数的值肯定会在方法前赋值returns。
在这方面,out
参数是从方法返回的值。
编译器确实强制执行这些语义。以下代码将生成几个警告:
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)将允许您在方法调用中声明变量。
给定:
public static void Test(out int x, out int y)
{
x = 1;
y = 2;
}
C# 7 允许您这样做:
Test(out int x, out int y);
Console.WriteLine($"x = {x}, y = {y}");
由于变量是在同一条语句中声明和初始化的,因此这种语法使某些东西变得更加明显"returned"。
同样在 C# 7 中,您可以使用元组代替 out
,我认为后者更好(并且与 lambda 一起工作得更好!)。
上面的例子在C#7中可以重写如下:
public static (int x, int y) Test()
{
int x = 1;
int y = 2;
return (x, y);
}
那么你可以这样做:
(int x, int y) = Test();
Console.WriteLine($"x = {x}, y = {y}");
你说得对,这个方法最多只能return(你所说的)一件事。或者,根据您的声明(return 类型 void
),当方法完成时,它不会 return 任何调用代码。
如果您想从您的方法中获取多个值,您有两种选择:
Return一个
class
或struct
——那是一回事,但它可以包含多个值(那个东西的属性)根据您的示例,使用
out
修饰符将一些参数传递到方法中。out
与ref
相似,因为您的方法处理的是实际值而不是它的副本。但与ref
不同的是,该方法必须在方法完成之前为任何标记为out
的参数赋值(如果不这样做,您将收到编译器错误)。您可以有多个带有out
修饰符的参数。
所以这有点取决于你所说的 return 的意思。在 return 值的意义上,您的示例代码 return 什么都没有(它是用 return 类型 void
声明的),如果您将其更改为具有 return 最多可以输入 return 一件事作为它的 return 值。但是在告诉调用代码在方法中做了什么的意义上,然后使用 out
参数你可以为多个值做到这一点。