C# ref、val 和 out 对方法参数的含义是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13060/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What do ref, val and out mean on method parameters?
提问by Keith
I'm looking for a clear, concise and accurate answer.
我正在寻找一个清晰、简洁和准确的答案。
Ideally as the actual answer, although links to good explanations welcome.
理想情况下作为实际答案,尽管欢迎提供良好解释的链接。
This also applies to VB.Net, but the keywords are different - ByRef
and ByVal
.
这也适用于 VB.Net,但关键字不同 -ByRef
和ByVal
.
采纳答案by Zooba
By default (in C#), passing an object to a function actually passes a copy of the reference to that object. Changing the parameter itself only changes the value in the parameter, and not the variable that was specified.
默认情况下(在 C# 中),将对象传递给函数实际上是将引用的副本传递给该对象。更改参数本身只会更改参数中的值,而不是指定的变量。
void Test1(string param)
{
param = "new value";
}
string s1 = "initial value";
Test1(s1);
// s1 == "initial value"
Using out
or ref
passes a reference to the variable specified in the call to the function. Any changes to the value of an out
or ref
parameter will be passed back to the caller.
使用out
或ref
传递对函数调用中指定的变量的引用。对out
或ref
参数值的任何更改都将传递回调用方。
Both out
and ref
behave identically except for one slight difference: ref
parameters are required to be initialised before calling, while out
parameters can be uninitialised. By extension, ref
parameters are guaranteed to be initialised at the start of the method, while out
parameters are treated as uninitialised.
无论out
和ref
行为相同,除了一个细微的差别:ref
需要参数调用之前被初始化,而out
参数可以未初始化。通过扩展,ref
参数保证在方法开始时被初始化,而out
参数被视为未初始化。
void Test2(ref string param)
{
param = "new value";
}
void Test3(out string param)
{
// Use of param here will not compile
param = "another value";
}
string s2 = "initial value";
string s3;
Test2(ref s2);
// s2 == "new value"
// Test2(ref s3); // Passing ref s3 will not compile
Test3(out s2);
// s2 == "another value"
Test3(out s3);
// s3 == "another value"
Edit: As dppoints out, the difference between out
and ref
is only enforced by the C# compiler, not by the CLR. As far as I know, VB has no equivalent for out
and implements ref
(as ByRef
) only, matching the support of the CLR.
编辑:作为DP指出,之间的差异out
,并ref
仅由C#编译器执行的,而不是由CLR。据我所知,VB 没有等价物,仅out
实现ref
(as ByRef
),与 CLR 的支持相匹配。
回答by Keith
out
means that the parameter will be initialised by the method:
out
意味着参数将被方法初始化:
int result; //not initialised
if( int.TryParse( "123", out result ) )
//result is now 123
else
//if TryParse failed result has still be
// initialised to its default value (0)
ref
will force the underlying reference to be passed:
ref
将强制传递基础引用:
void ChangeMyClass1( MyClass input ) {
input.MyProperty = "changed by 1";
input = null;
//can't see input anymore ...
// I've only nulled my local scope's reference
}
void ChangeMyClass2( ref MyClass input ) {
input.MyProperty = "changed by 2";
input = null;
//the passed reference is now null too.
}
MyClass tester = new MyClass { MyProperty = "initial value" };
ChangeMyClass1( tester );
// now tester.MyProperty is "changed by 1"
ChangeMyClass2( ref tester );
// now tester is null
回答by sven
One of my own questions at stackoverflow handles this topic too.
It handles about "pass by reference" and "pass by value"in different types of languages, c# is includedso maybe you can find some extra information there as well.
我自己在 stackoverflow 上的一个问题也处理了这个话题。
它处理不同类型语言中的“按引用传递”和“按值传递”,包括 c#,所以也许您也可以在那里找到一些额外的信息。
Basically it comes down to:
基本上归结为:
- ref: the parameter with the ref keyword will be passed by reference
- out: the parameter with the out keyword will be treated as an output parameter
- ref:带有 ref 关键字的参数将通过引用传递
- out:带有 out 关键字的参数将被视为输出参数
but that's really the most basic answer you can give, as it is a little more complex than it is stated here
但这确实是您可以给出的最基本的答案,因为它比此处说明的要复杂一些
回答by denis phillips
One additional note about ref vs. out: The distinction between the two is enforced by the C# compiler. The CLR does not distinguish between between out and ref. This means that you cannot have two methods whose signatures differ only by an out or ref
关于 ref 与 out 的附加说明:两者之间的区别由 C# 编译器强制执行。CLR 不区分 out 和 ref。这意味着您不能有两个方法的签名仅通过 out 或 ref 不同
void foo(int value) {}
// Only one of the following would be allowed
// valid to overload with ref
void foo(ref int value) {}
// OR with out
void foo(out int value) {}